sycommon-python-lib 0.2.5a0__tar.gz → 0.2.5a2__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 (282) hide show
  1. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/PKG-INFO +2 -2
  2. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/pyproject.toml +2 -2
  3. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/mcp/tool_loader.py +59 -9
  4. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/http_sandbox_backend.py +42 -9
  5. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/auth/__init__.py +23 -0
  6. sycommon_python_lib-0.2.5a2/src/sycommon/auth/oa_cache.py +95 -0
  7. sycommon_python_lib-0.2.5a2/src/sycommon/auth/oa_crypto.py +60 -0
  8. sycommon_python_lib-0.2.5a2/src/sycommon/auth/oa_service.py +201 -0
  9. sycommon_python_lib-0.2.5a2/src/sycommon/tests/test_oa_login.py +229 -0
  10. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/PKG-INFO +2 -2
  11. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/SOURCES.txt +4 -0
  12. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/requires.txt +1 -1
  13. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/README.md +0 -0
  14. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/setup.cfg +0 -0
  15. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/__init__.py +0 -0
  16. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/cli.py +0 -0
  17. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/core/__init__.py +0 -0
  18. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/core/console.py +0 -0
  19. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/core/models.py +0 -0
  20. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/core/project.py +0 -0
  21. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/core/utils.py +0 -0
  22. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/__init__.py +0 -0
  23. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/README.md.tpl +0 -0
  24. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/__init__.py +0 -0
  25. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/__init__.py.tpl +0 -0
  26. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/main_agent.py.tpl +0 -0
  27. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/nodes/__init__.py.tpl +0 -0
  28. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/nodes/example_node.py.tpl +0 -0
  29. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/states/__init__.py.tpl +0 -0
  30. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/agent/states/agent_state.py.tpl +0 -0
  31. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/api/__init__.py.tpl +0 -0
  32. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/api/query.py.tpl +0 -0
  33. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/api/sse/__init__.py.tpl +0 -0
  34. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/api/sse/agent.py.tpl +0 -0
  35. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/app.py.tpl +0 -0
  36. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/client/__init__.py.tpl +0 -0
  37. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/db/__init__.py.tpl +0 -0
  38. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/db/model/__init__.py.tpl +0 -0
  39. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/db/model/entity.py.tpl +0 -0
  40. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/db/service.py.tpl +0 -0
  41. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/model/__init__.py.tpl +0 -0
  42. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/model/parse.py.tpl +0 -0
  43. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/tools/__init__.py.tpl +0 -0
  44. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/agent/tools/mq.py.tpl +0 -0
  45. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/.env.tpl +0 -0
  46. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/.gitignore.tpl +0 -0
  47. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/Dockerfile.tpl +0 -0
  48. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/README.md.tpl +0 -0
  49. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/__init__.py +0 -0
  50. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/app.py.tpl +0 -0
  51. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/app.yaml.tpl +0 -0
  52. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/client/FileServiceClient.py.tpl +0 -0
  53. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/client/__init__.py.tpl +0 -0
  54. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/model/__init__.py.tpl +0 -0
  55. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/model/file_info.py.tpl +0 -0
  56. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/base/requirements.txt.tpl +0 -0
  57. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/README.md.tpl +0 -0
  58. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/__init__.py +0 -0
  59. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/app.py.tpl +0 -0
  60. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/commands/__init__.py.tpl +0 -0
  61. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/commands/hello.py.tpl +0 -0
  62. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/pyproject.toml.tpl +0 -0
  63. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/cli/tools/__init__.py.tpl +0 -0
  64. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/README.md.tpl +0 -0
  65. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/__init__.py +0 -0
  66. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/api/__init__.py.tpl +0 -0
  67. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/api/echo.py.tpl +0 -0
  68. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/api/sse/__init__.py.tpl +0 -0
  69. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/api/sse/echo.py.tpl +0 -0
  70. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/app.py.tpl +0 -0
  71. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/client/__init__.py.tpl +0 -0
  72. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/model/__init__.py.tpl +0 -0
  73. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/tools/__init__.py.tpl +0 -0
  74. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/command/templates/web/tools/mq.py.tpl +0 -0
  75. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/nexus/__init__.py +0 -0
  76. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/__init__.py +0 -0
  77. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/__main__.py +0 -0
  78. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/agents/__init__.py +0 -0
  79. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/agents/factory.py +0 -0
  80. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/agents/prompts.py +0 -0
  81. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/__init__.py +0 -0
  82. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/browser.py +0 -0
  83. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/__init__.py +0 -0
  84. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/console.py +0 -0
  85. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/dom.py +0 -0
  86. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/network.py +0 -0
  87. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/page_errors.py +0 -0
  88. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/performance.py +0 -0
  89. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/capabilities/screenshot.py +0 -0
  90. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/client.py +0 -0
  91. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/protocol.py +0 -0
  92. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cdp/repl.py +0 -0
  93. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/cli.py +0 -0
  94. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/__init__.py +0 -0
  95. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/cdp_cmd.py +0 -0
  96. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/chat_cmd.py +0 -0
  97. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/create_cmd.py +0 -0
  98. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/evaluate_cmd.py +0 -0
  99. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/init_cmd.py +0 -0
  100. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/memory_cmd.py +0 -0
  101. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/resume_cmd.py +0 -0
  102. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/rollback_cmd.py +0 -0
  103. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/commands/run_cmd.py +0 -0
  104. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/__init__.py +0 -0
  105. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/backend.py +0 -0
  106. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/config.py +0 -0
  107. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/display.py +0 -0
  108. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/git_integration.py +0 -0
  109. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/llm.py +0 -0
  110. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/core/state.py +0 -0
  111. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/evaluate/__init__.py +0 -0
  112. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/evaluate/api_evaluator.py +0 -0
  113. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/__init__.py +0 -0
  114. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/compressor.py +0 -0
  115. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/full.py +0 -0
  116. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/hot.py +0 -0
  117. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/manager.py +0 -0
  118. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/memory/warm.py +0 -0
  119. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/mode/__init__.py +0 -0
  120. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/mode/create.py +0 -0
  121. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/mode/optimize.py +0 -0
  122. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/models/__init__.py +0 -0
  123. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/models/config_models.py +0 -0
  124. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/__init__.py +0 -0
  125. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/baseline_tests.py +0 -0
  126. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/checkpoint.py +0 -0
  127. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/convergence.py +0 -0
  128. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/diagnosis.py +0 -0
  129. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/engine.py +0 -0
  130. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/environment.py +0 -0
  131. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/experience.py +0 -0
  132. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/harness_prompts.py +0 -0
  133. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/history.py +0 -0
  134. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/optimization_logger.py +0 -0
  135. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/pre_validation.py +0 -0
  136. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/reward.py +0 -0
  137. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/strategy_bandit.py +0 -0
  138. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/strategy_generator.py +0 -0
  139. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/rl/strategy_prompts.py +0 -0
  140. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycli/skills/__init__.py +0 -0
  141. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/__init__.py +0 -0
  142. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/__init__.py +0 -0
  143. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/agent_manager.py +0 -0
  144. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/chat_events.py +0 -0
  145. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/deep_agent.py +0 -0
  146. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/mcp/__init__.py +0 -0
  147. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/mcp/models.py +0 -0
  148. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/multi_agent_team.py +0 -0
  149. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/__init__.py +0 -0
  150. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/file_ops.py +0 -0
  151. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/minio_sync.py +0 -0
  152. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/sandbox_pool.py +0 -0
  153. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/sandbox_recovery.py +0 -0
  154. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/sandbox/session.py +0 -0
  155. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/agent/summarization_utils.py +0 -0
  156. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/auth/ldap_service.py +0 -0
  157. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/auth/wecom_ldap_service.py +0 -0
  158. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/Config.py +0 -0
  159. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/DatabaseConfig.py +0 -0
  160. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/ElasticsearchConfig.py +0 -0
  161. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/EmbeddingConfig.py +0 -0
  162. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/LLMConfig.py +0 -0
  163. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/LangfuseConfig.py +0 -0
  164. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/MQConfig.py +0 -0
  165. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/PgConfig.py +0 -0
  166. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/RedisConfig.py +0 -0
  167. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/RerankerConfig.py +0 -0
  168. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/SentryConfig.py +0 -0
  169. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/XxlJobConfig.py +0 -0
  170. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/config/__init__.py +0 -0
  171. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/async_base_db_service.py +0 -0
  172. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/async_database_service.py +0 -0
  173. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/base_db_service.py +0 -0
  174. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/database_service.py +0 -0
  175. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/elasticsearch_service.py +0 -0
  176. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/pg_checkpoint_service.py +0 -0
  177. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/redis_service.py +0 -0
  178. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/database/token_usage_db_service.py +0 -0
  179. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/health/__init__.py +0 -0
  180. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/health/health_check.py +0 -0
  181. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/health/metrics.py +0 -0
  182. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/health/ping.py +0 -0
  183. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/heartbeat_process/__init__.py +0 -0
  184. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/heartbeat_process/heartbeat_config.py +0 -0
  185. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/heartbeat_process/heartbeat_process_manager.py +0 -0
  186. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/heartbeat_process/heartbeat_process_worker.py +0 -0
  187. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/__init__.py +0 -0
  188. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/embedding.py +0 -0
  189. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/get_llm.py +0 -0
  190. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/llm_logger.py +0 -0
  191. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/llm_tokens.py +0 -0
  192. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/llm_with_token_tracking.py +0 -0
  193. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/native_with_fallback_runnable.py +0 -0
  194. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/output_fixing_runnable.py +0 -0
  195. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/struct_token.py +0 -0
  196. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/sy_langfuse.py +0 -0
  197. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/token_usage_es_service.py +0 -0
  198. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/token_usage_mysql_service.py +0 -0
  199. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/llm/usage_token.py +0 -0
  200. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/__init__.py +0 -0
  201. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/async_sql_logger.py +0 -0
  202. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/kafka_log.py +0 -0
  203. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/logger_levels.py +0 -0
  204. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/logger_wrapper.py +0 -0
  205. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/process_logger.py +0 -0
  206. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/logging/sql_logger.py +0 -0
  207. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/__init__.py +0 -0
  208. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/background_execution.py +0 -0
  209. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/context.py +0 -0
  210. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/cors.py +0 -0
  211. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/docs.py +0 -0
  212. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/exception.py +0 -0
  213. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/middleware.py +0 -0
  214. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/monitor_memory.py +0 -0
  215. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/mq.py +0 -0
  216. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/sandbox.py +0 -0
  217. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/timeout.py +0 -0
  218. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/token_tracking.py +0 -0
  219. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/tool_result_truncation.py +0 -0
  220. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/middleware/traceid.py +0 -0
  221. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/__init__.py +0 -0
  222. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/base_http.py +0 -0
  223. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/log.py +0 -0
  224. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/mqlistener_config.py +0 -0
  225. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/mqmsg_model.py +0 -0
  226. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/mqsend_config.py +0 -0
  227. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/sandbox.py +0 -0
  228. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/sso_user.py +0 -0
  229. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/token_usage.py +0 -0
  230. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/token_usage_mysql.py +0 -0
  231. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/models/xxljob_handler_config.py +0 -0
  232. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/notice/__init__.py +0 -0
  233. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/notice/uvicorn_monitor.py +0 -0
  234. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/notice/wecom_message.py +0 -0
  235. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/process_pool_consumer.py +0 -0
  236. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_client.py +0 -0
  237. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_pool.py +0 -0
  238. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service.py +0 -0
  239. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service_client_manager.py +0 -0
  240. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service_connection_monitor.py +0 -0
  241. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service_consumer_manager.py +0 -0
  242. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service_core.py +0 -0
  243. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/rabbitmq/rabbitmq_service_producer_manager.py +0 -0
  244. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/sentry/__init__.py +0 -0
  245. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/sentry/sy_sentry.py +0 -0
  246. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/services.py +0 -0
  247. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/sse/__init__.py +0 -0
  248. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/sse/event.py +0 -0
  249. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/sse/sse.py +0 -0
  250. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/__init__.py +0 -0
  251. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/example.py +0 -0
  252. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/example2.py +0 -0
  253. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/feign.py +0 -0
  254. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/feign_client.py +0 -0
  255. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_client_base.py +0 -0
  256. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_config_manager.py +0 -0
  257. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_heartbeat_manager.py +0 -0
  258. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_service.py +0 -0
  259. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_service_discovery.py +0 -0
  260. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/nacos_service_registration.py +0 -0
  261. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/synacos/param.py +0 -0
  262. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/deep_agent_server.py +0 -0
  263. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_deep_agent.py +0 -0
  264. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_email.py +0 -0
  265. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_mq.py +0 -0
  266. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_real_summarization.py +0 -0
  267. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_summarization_config.py +0 -0
  268. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tests/test_summarization_real.py +0 -0
  269. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/__init__.py +0 -0
  270. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/async_utils.py +0 -0
  271. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/docs.py +0 -0
  272. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/env.py +0 -0
  273. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/merge_headers.py +0 -0
  274. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/snowflake.py +0 -0
  275. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/syemail.py +0 -0
  276. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/tools/timing.py +0 -0
  277. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/xxljob/__init__.py +0 -0
  278. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon/xxljob/xxljob_service.py +0 -0
  279. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/dependency_links.txt +0 -0
  280. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/entry_points.txt +0 -0
  281. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/src/sycommon_python_lib.egg-info/top_level.txt +0 -0
  282. {sycommon_python_lib-0.2.5a0 → sycommon_python_lib-0.2.5a2}/tests/test_sycli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.2.5a0
3
+ Version: 0.2.5a2
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -9,7 +9,7 @@ Requires-Dist: aiohttp>=3.13.5
9
9
  Requires-Dist: aiomysql>=0.3.2
10
10
  Requires-Dist: anyio>=4.12.1
11
11
  Requires-Dist: decorator>=5.3.1
12
- Requires-Dist: deepagents>=0.6.3
12
+ Requires-Dist: deepagents>=0.6.1
13
13
  Requires-Dist: elasticsearch>=9.4.0
14
14
  Requires-Dist: fastapi>=0.136.1
15
15
  Requires-Dist: jinja2>=3.1.6
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sycommon-python-lib"
3
- version = "0.2.5a0"
3
+ version = "0.2.5a2"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -10,7 +10,7 @@ dependencies = [
10
10
  "aiomysql>=0.3.2",
11
11
  "anyio>=4.12.1",
12
12
  "decorator>=5.3.1",
13
- "deepagents>=0.6.3",
13
+ "deepagents>=0.6.1",
14
14
  "elasticsearch>=9.4.0",
15
15
  "fastapi>=0.136.1",
16
16
  "jinja2>=3.1.6",
@@ -72,8 +72,36 @@ def wrap_tool_with_error_handler(
72
72
  return tool
73
73
 
74
74
 
75
+ def _make_user_id_interceptor(user_id: str):
76
+ """创建 MCP 工具调用拦截器,注入 X-User-Id 和 X-OA-Session-Id header"""
77
+ from langchain_mcp_adapters.interceptors import MCPToolCallRequest, MCPToolCallResult
78
+ from typing import Callable, Awaitable
79
+
80
+ async def inject_user_id(
81
+ request: MCPToolCallRequest,
82
+ handler: Callable[[MCPToolCallRequest], Awaitable[MCPToolCallResult]],
83
+ ) -> MCPToolCallResult:
84
+ headers = dict(request.headers or {})
85
+ headers["X-User-Id"] = user_id
86
+
87
+ # 自动获取 OA session_id 注入 header
88
+ try:
89
+ from sycommon.auth.oa_cache import oa_login_with_cache
90
+ success, _, session_id = await oa_login_with_cache(user_id)
91
+ if success and session_id:
92
+ headers["X-OA-Session-Id"] = session_id
93
+ except Exception:
94
+ pass
95
+
96
+ request = request.override(headers=headers)
97
+ return await handler(request)
98
+
99
+ return inject_user_id
100
+
101
+
75
102
  async def load_mcp_tools(
76
103
  configs: List[MCPServerConfig],
104
+ user_id: str = None,
77
105
  on_tool_success: Optional[Callable[[str, str], Awaitable[None]]] = None,
78
106
  on_tool_error: Optional[Callable[[str, str, str], Awaitable[None]]] = None,
79
107
  on_batch_available: Optional[Callable[[str, list], Awaitable[None]]] = None,
@@ -85,6 +113,7 @@ async def load_mcp_tools(
85
113
 
86
114
  Args:
87
115
  configs: MCP 服务器配置列表(仅 enabled 的会被处理)
116
+ user_id: 当前用户 ID,通过 interceptor 注入到每次 MCP 工具调用的 header 中
88
117
  on_tool_success: 单个工具调用成功回调
89
118
  on_tool_error: 单个工具调用失败回调
90
119
  on_batch_available: 服务器连接成功后批量标记工具可用回调 (config_id, tool_names)
@@ -94,10 +123,16 @@ async def load_mcp_tools(
94
123
  if not enabled_configs:
95
124
  return []
96
125
 
126
+ # 构建 interceptor 链
127
+ interceptors = []
128
+ if user_id:
129
+ interceptors.append(_make_user_id_interceptor(user_id))
130
+
97
131
  all_tools = []
98
132
  for config in enabled_configs:
99
133
  try:
100
134
  from langchain_mcp_adapters.client import MultiServerMCPClient
135
+ from langchain_mcp_adapters.tools import load_mcp_tools as _load_tools
101
136
 
102
137
  key = sanitize_name(config.name)
103
138
  client_config = {
@@ -109,22 +144,37 @@ async def load_mcp_tools(
109
144
  }
110
145
 
111
146
  client = MultiServerMCPClient(client_config)
112
- tools = await client.get_tools()
147
+ session = await client.session_for(key)
148
+ await session.initialize()
149
+
150
+ from langchain_mcp_adapters.tools import _list_all_tools
151
+ raw_tools = await _list_all_tools(session)
113
152
 
114
153
  original_names = []
115
- for tool in tools:
154
+ for tool in raw_tools:
116
155
  original_name = tool.name
117
156
  original_names.append(original_name)
118
- tool.name = f"mcp__{key}__{original_name}"
119
- if tool.description and not tool.description.startswith("[MCP"):
120
- tool.description = f"[MCP:{config.name}] {tool.description}"
157
+
158
+ # 使用 convert_mcp_tool_to_langchain_tool interceptors
159
+ from langchain_mcp_adapters.tools import convert_mcp_tool_to_langchain_tool
160
+ lc_tool = convert_mcp_tool_to_langchain_tool(
161
+ session,
162
+ tool,
163
+ connection=client_config[key],
164
+ tool_interceptors=interceptors if interceptors else None,
165
+ server_name=config.name,
166
+ tool_name_prefix=False,
167
+ )
168
+
169
+ lc_tool.name = f"mcp__{key}__{original_name}"
170
+ if lc_tool.description and not lc_tool.description.startswith("[MCP"):
171
+ lc_tool.description = f"[MCP:{config.name}] {lc_tool.description}"
121
172
  wrap_tool_with_error_handler(
122
- tool, config.id, config.name, original_name,
173
+ lc_tool, config.id, config.name, original_name,
123
174
  on_tool_success=on_tool_success,
124
175
  on_tool_error=on_tool_error,
125
176
  )
126
-
127
- all_tools.extend(tools)
177
+ all_tools.append(lc_tool)
128
178
 
129
179
  if on_batch_available:
130
180
  try:
@@ -132,7 +182,7 @@ async def load_mcp_tools(
132
182
  except Exception as e:
133
183
  SYLogger.warning(f"[MCP] 写入工具状态失败: {e}")
134
184
 
135
- SYLogger.info(f"[MCP] 服务器 '{config.name}' 加载了 {len(tools)} 个工具")
185
+ SYLogger.info(f"[MCP] 服务器 '{config.name}' 加载了 {len(raw_tools)} 个工具")
136
186
 
137
187
  except Exception as e:
138
188
  SYLogger.warning(f"[MCP] 服务器 '{config.name}' ({config.server_url}) 连接失败,跳过: {e}")
@@ -110,6 +110,10 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
110
110
  self._auto_sync = auto_sync
111
111
  self._synced = False
112
112
  self._workspace_verified = False
113
+ self._local_mode: Optional[bool] = None
114
+
115
+ # Token authentication
116
+ self._token = os.environ.get("SANDBOX_TOKEN", "")
113
117
 
114
118
  # Nacos 配置(用于故障转移)
115
119
  self._nacos_service_name = nacos_service_name
@@ -309,6 +313,16 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
309
313
  finally:
310
314
  self._in_failover = False
311
315
 
316
+ def _build_headers(self) -> dict:
317
+ """Build common headers for all requests (trace ID + token auth)."""
318
+ headers = {}
319
+ trace_id = SYLogger.get_trace_id()
320
+ if trace_id:
321
+ headers["x-traceid-header"] = str(trace_id)
322
+ if self._token:
323
+ headers["X-Sandbox-Token"] = self._token
324
+ return headers
325
+
312
326
  def _post_sync_with_failover(self, endpoint: str, data: dict, timeout: int = None) -> dict:
313
327
  """带故障转移的同步 POST 请求"""
314
328
  actual_timeout = timeout if timeout is not None else self._timeout
@@ -320,10 +334,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
320
334
  http_timeout = actual_timeout + 30
321
335
  max_retries = 3
322
336
 
323
- trace_id = SYLogger.get_trace_id()
324
- headers = {}
325
- if trace_id:
326
- headers["x-traceid-header"] = str(trace_id)
337
+ headers = self._build_headers()
327
338
 
328
339
  url = f"{self._base_url}{endpoint}"
329
340
  SYLogger.info(f"[Sandbox] POST 请求开始: {url}, timeout={http_timeout}s, command_timeout={actual_timeout}s")
@@ -376,6 +387,8 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
376
387
  headers = {"Content-Type": "application/json"}
377
388
  if trace_id:
378
389
  headers["x-traceid-header"] = str(trace_id)
390
+ if self._token:
391
+ headers["X-Sandbox-Token"] = self._token
379
392
 
380
393
  url = f"{self._base_url}{endpoint}"
381
394
  SYLogger.info(f"[Sandbox] Async POST 请求开始: {url}, timeout={http_timeout}s")
@@ -1275,10 +1288,7 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
1275
1288
 
1276
1289
  def health_check(self, timeout: int = 10) -> dict:
1277
1290
  """健康检查(快速检查,默认10秒超时)"""
1278
- trace_id = SYLogger.get_trace_id()
1279
- headers = {}
1280
- if trace_id:
1281
- headers["x-traceid-header"] = str(trace_id)
1291
+ headers = self._build_headers()
1282
1292
 
1283
1293
  url = f"{self._base_url}{SANDBOX_API_PREFIX}/health"
1284
1294
  SYLogger.info(f"[Sandbox] 健康检查: {url}, timeout={timeout}s")
@@ -1299,11 +1309,12 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
1299
1309
  async def ahealth_check(self, timeout: int = 10) -> dict:
1300
1310
  """异步健康检查"""
1301
1311
  try:
1312
+ headers = self._build_headers()
1302
1313
  url = f"{self._base_url}{SANDBOX_API_PREFIX}/health"
1303
1314
  timeout_obj = aiohttp.ClientTimeout(total=timeout)
1304
1315
  connector = aiohttp.TCPConnector(ssl=_SSL_CONTEXT)
1305
1316
  async with aiohttp.ClientSession(connector=connector) as session:
1306
- async with session.get(url, timeout=timeout_obj) as resp:
1317
+ async with session.get(url, headers=headers, timeout=timeout_obj) as resp:
1307
1318
  resp.raise_for_status()
1308
1319
  result = await resp.json()
1309
1320
  SYLogger.info(f"[Sandbox] 异步健康检查成功: {result}")
@@ -1320,3 +1331,25 @@ class HTTPSandboxBackend(FileOperationsMixin, SandboxBackendProtocol):
1320
1331
  except Exception as e:
1321
1332
  SYLogger.warning(f"[Sandbox] 沙箱不可用: {e}")
1322
1333
  return False
1334
+
1335
+ def is_local_mode(self) -> bool:
1336
+ """检查沙箱是否运行在 LocalMode(本地直接访问文件系统,跳过上传/同步)"""
1337
+ if self._local_mode is not None:
1338
+ return self._local_mode
1339
+ try:
1340
+ result = self.health_check(timeout=5)
1341
+ self._local_mode = result.get("mode") == "local"
1342
+ except Exception:
1343
+ self._local_mode = False
1344
+ return self._local_mode
1345
+
1346
+ async def ais_local_mode(self) -> bool:
1347
+ """异步检查沙箱是否运行在 LocalMode"""
1348
+ if self._local_mode is not None:
1349
+ return self._local_mode
1350
+ try:
1351
+ result = await self.ahealth_check(timeout=5)
1352
+ self._local_mode = result.get("mode") == "local"
1353
+ except Exception:
1354
+ self._local_mode = False
1355
+ return self._local_mode
@@ -34,6 +34,20 @@ from sycommon.auth.wecom_ldap_service import (
34
34
  LDAPFullUser,
35
35
  )
36
36
 
37
+ from sycommon.auth.oa_service import (
38
+ OAConfig,
39
+ OAAuthService,
40
+ OAUser,
41
+ OAAuthResult,
42
+ )
43
+ from sycommon.auth.oa_cache import (
44
+ set_oa_credential,
45
+ get_oa_credential,
46
+ delete_oa_credential,
47
+ has_oa_credential,
48
+ oa_login_with_cache,
49
+ )
50
+
37
51
  __all__ = [
38
52
  "LDAPConfig",
39
53
  "LDAPAuthService",
@@ -43,4 +57,13 @@ __all__ = [
43
57
  "WeComLDAPService",
44
58
  "WeComLDAPUser",
45
59
  "LDAPFullUser",
60
+ "OAConfig",
61
+ "OAAuthService",
62
+ "OAUser",
63
+ "OAAuthResult",
64
+ "set_oa_credential",
65
+ "get_oa_credential",
66
+ "delete_oa_credential",
67
+ "has_oa_credential",
68
+ "oa_login_with_cache",
46
69
  ]
@@ -0,0 +1,95 @@
1
+ """OA 凭据 Redis 缓存服务
2
+
3
+ 加密存储用户 LDAP 凭据到 Redis,供 OA 登录使用。
4
+ 每次写入覆盖旧值。
5
+ OA session_id 也缓存到 Redis,避免重复登录。
6
+ """
7
+
8
+ from typing import Optional
9
+
10
+ from sycommon.auth.oa_crypto import encrypt_credential, decrypt_credential
11
+ from sycommon.logging.kafka_log import SYLogger
12
+
13
+ _CRED_PREFIX = "digital_work:oa_credential"
14
+ _SESSION_PREFIX = "digital_work:oa_session"
15
+
16
+
17
+ def _cred_key(user_id: str) -> str:
18
+ return f"{_CRED_PREFIX}:{user_id}"
19
+
20
+
21
+ def _session_key(user_id: str) -> str:
22
+ return f"{_SESSION_PREFIX}:{user_id}"
23
+
24
+
25
+ async def set_oa_credential(user_id: str, login_id: str, password: str) -> None:
26
+ """加密存储 LDAP 凭据到 Redis(覆盖)"""
27
+ from sycommon.database.redis_service import RedisService
28
+ encrypted = encrypt_credential({"login_id": login_id, "password": password})
29
+ await RedisService.set(_cred_key(user_id), encrypted)
30
+ SYLogger.info(f"[OA] 已缓存用户 {user_id} 的 LDAP 凭据")
31
+
32
+
33
+ async def get_oa_credential(user_id: str) -> Optional[dict]:
34
+ """从 Redis 读取并解密 LDAP 凭据"""
35
+ from sycommon.database.redis_service import RedisService
36
+ raw = await RedisService.get(_cred_key(user_id))
37
+ if not raw:
38
+ return None
39
+ return decrypt_credential(raw)
40
+
41
+
42
+ async def delete_oa_credential(user_id: str) -> None:
43
+ """删除 Redis 中的 LDAP 凭据和 session"""
44
+ from sycommon.database.redis_service import RedisService
45
+ await RedisService.delete(_cred_key(user_id))
46
+ await RedisService.delete(_session_key(user_id))
47
+ SYLogger.info(f"[OA] 已删除用户 {user_id} 的 LDAP 凭据")
48
+
49
+
50
+ async def has_oa_credential(user_id: str) -> bool:
51
+ """检查用户是否已有缓存的 LDAP 凭据"""
52
+ from sycommon.database.redis_service import RedisService
53
+ raw = await RedisService.get(_cred_key(user_id))
54
+ return raw is not None
55
+
56
+
57
+ async def set_oa_session(user_id: str, session_id: str) -> None:
58
+ """缓存 OA session_id 到 Redis(30 分钟过期,与 OA 服务端保持一致)"""
59
+ from sycommon.database.redis_service import RedisService
60
+ await RedisService.set(_session_key(user_id), session_id, ex=1800)
61
+
62
+
63
+ async def get_cached_oa_session(user_id: str) -> Optional[str]:
64
+ """获取缓存的 OA session_id(可能已过期)"""
65
+ from sycommon.database.redis_service import RedisService
66
+ return await RedisService.get(_session_key(user_id))
67
+
68
+
69
+ async def oa_login_with_cache(user_id: str) -> tuple[bool, str, Optional[str]]:
70
+ """从 Redis 获取 OA session,过期则重新登录。
71
+
72
+ Returns:
73
+ (success, message, session_id)
74
+ """
75
+ # 优先使用缓存的 session
76
+ cached_session = await get_cached_oa_session(user_id)
77
+ if cached_session:
78
+ return True, "OA session有效", cached_session
79
+
80
+ # 缓存过期,重新登录
81
+ cred = await get_oa_credential(user_id)
82
+ if not cred:
83
+ return False, "NEED_OA_AUTH", None
84
+
85
+ from sycommon.auth.oa_service import OAConfig, OAAuthService
86
+ config = OAConfig(login_id=cred["login_id"], password=cred["password"])
87
+ result = await OAAuthService(config).login()
88
+
89
+ if result.success:
90
+ await set_oa_session(user_id, result.user.session_id)
91
+ SYLogger.info(f"[OA] 用户 {user_id} 登录成功")
92
+ return True, "OA登录成功", result.user.session_id
93
+ else:
94
+ SYLogger.warning(f"[OA] 用户 {user_id} 登录失败: {result.error}")
95
+ return False, f"OA登录失败: {result.error}", None
@@ -0,0 +1,60 @@
1
+ """OA 凭据加密工具
2
+
3
+ 使用 AES-256-GCM 加密 LDAP 凭据,密钥从 Nacos 配置或环境变量读取。
4
+ """
5
+
6
+ import base64
7
+ import json
8
+ import os
9
+ from typing import Optional
10
+
11
+ from cryptography.hazmat.primitives.ciphers.aead import AESGCM
12
+
13
+ from sycommon.logging.kafka_log import SYLogger
14
+
15
+ NONCE_SIZE = 12
16
+ _ENV_KEY = "OA_CREDENTIAL_ENCRYPT_KEY"
17
+
18
+
19
+ def _get_key() -> bytes:
20
+ """获取加密密钥(优先环境变量,其次 Nacos 配置)"""
21
+ b64 = os.environ.get(_ENV_KEY)
22
+ if not b64:
23
+ try:
24
+ from sycommon.config.Config import Config
25
+ b64 = Config().config.get("llm", {}).get("OA", {}).get("credential_encrypt_key", "")
26
+ except Exception:
27
+ pass
28
+ if not b64:
29
+ raise ValueError(
30
+ f"未配置 OA 凭据加密密钥,请设置环境变量 {_ENV_KEY} 或 Nacos 配置 OA.credential_encrypt_key"
31
+ )
32
+ key = base64.b64decode(b64)
33
+ if len(key) != 32:
34
+ raise ValueError("加密密钥长度必须为 32 字节 (AES-256)")
35
+ return key
36
+
37
+
38
+ def encrypt_credential(data: dict) -> str:
39
+ """加密凭据字典,返回 base64 编码的密文"""
40
+ key = _get_key()
41
+ plaintext = json.dumps(data, ensure_ascii=False).encode("utf-8")
42
+ aesgcm = AESGCM(key)
43
+ nonce = os.urandom(NONCE_SIZE)
44
+ ciphertext = aesgcm.encrypt(nonce, plaintext, None)
45
+ return base64.b64encode(nonce + ciphertext).decode("ascii")
46
+
47
+
48
+ def decrypt_credential(raw: str) -> Optional[dict]:
49
+ """解密 base64 编码的密文,返回凭据字典"""
50
+ try:
51
+ key = _get_key()
52
+ blob = base64.b64decode(raw)
53
+ nonce = blob[:NONCE_SIZE]
54
+ ciphertext = blob[NONCE_SIZE:]
55
+ aesgcm = AESGCM(key)
56
+ plaintext = aesgcm.decrypt(nonce, ciphertext, None)
57
+ return json.loads(plaintext)
58
+ except Exception as e:
59
+ SYLogger.error(f"[OA] 凭据解密失败: {e}")
60
+ return None
@@ -0,0 +1,201 @@
1
+ """
2
+ OA 登录服务
3
+
4
+ 提供基于 SOAP 协议的 OA 系统登录认证功能。
5
+ """
6
+
7
+ import asyncio
8
+ from typing import Optional
9
+ from pydantic import BaseModel
10
+
11
+ from sycommon.logging.kafka_log import SYLogger
12
+
13
+
14
+ class OAConfig(BaseModel):
15
+ """OA 配置"""
16
+
17
+ base_url: str = "https://oa.syholdings.com"
18
+ doc_service: Optional[str] = None
19
+ login_id: str = ""
20
+ password: str = ""
21
+
22
+ @property
23
+ def doc_service_url(self) -> str:
24
+ if self.doc_service:
25
+ return self.doc_service
26
+ return f"{self.base_url}/services/DocService"
27
+
28
+ @classmethod
29
+ def from_config(cls) -> "OAConfig":
30
+ from sycommon.config.Config import Config
31
+
32
+ oa_config = Config().config.get("OA", {})
33
+ return cls(
34
+ base_url=oa_config.get("base_url", "https://oa.syholdings.com"),
35
+ doc_service=oa_config.get("doc_service"),
36
+ login_id=oa_config.get("login_id", ""),
37
+ password=oa_config.get("password", ""),
38
+ )
39
+
40
+
41
+ class OAUser(BaseModel):
42
+ """OA 用户信息"""
43
+
44
+ session_id: Optional[str] = None
45
+ login_id: str
46
+
47
+
48
+ class OAAuthResult(BaseModel):
49
+ """OA 登录结果"""
50
+
51
+ success: bool
52
+ user: Optional[OAUser] = None
53
+ error: Optional[str] = None
54
+
55
+
56
+ class OAAuthService:
57
+ """OA 认证服务
58
+
59
+ 使用示例::
60
+
61
+ config = OAConfig(
62
+ base_url="https://oa.syholdings.com",
63
+ login_id="username",
64
+ password="password",
65
+ )
66
+ service = OAAuthService(config)
67
+ result = await service.login()
68
+ if result.success:
69
+ print(f"登录成功, session: {result.user.session_id}")
70
+ """
71
+
72
+ def __init__(self, config: OAConfig):
73
+ self.config = config
74
+
75
+ def _build_login_xml(self, login_id: Optional[str] = None,
76
+ password: Optional[str] = None) -> str:
77
+ """构建登录 SOAP 请求体"""
78
+ lid = login_id or self.config.login_id
79
+ pwd = password or self.config.password
80
+ return f"""<?xml version="1.0" encoding="UTF-8"?>
81
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
82
+ xmlns:doc="http://localhost/services/DocService">
83
+ <soapenv:Body>
84
+ <doc:login>
85
+ <doc:in0>{lid}</doc:in0>
86
+ <doc:in1>{pwd}</doc:in1>
87
+ <doc:in2>2</doc:in2>
88
+ <doc:in3>127.0.0.1</doc:in3>
89
+ </doc:login>
90
+ </soapenv:Body>
91
+ </soapenv:Envelope>"""
92
+
93
+ def _parse_login_response(self, response_text: str) -> OAAuthResult:
94
+ """解析登录响应"""
95
+ import xml.etree.ElementTree as ET
96
+
97
+ try:
98
+ root = ET.fromstring(response_text)
99
+ except ET.ParseError as e:
100
+ SYLogger.error(f"[OA] 响应 XML 解析失败: {e}")
101
+ return OAAuthResult(success=False, error=f"XML 解析失败: {e}")
102
+
103
+ # SOAP 命名空间
104
+ ns = {
105
+ "soapenv": "http://schemas.xmlsoap.org/soap/envelope/",
106
+ }
107
+
108
+ body = root.find("soapenv:Body", ns)
109
+ if body is None:
110
+ return OAAuthResult(success=False, error="响应缺少 Body")
111
+
112
+ # 查找登录返回值(可能是 loginReturn 或 out)
113
+ login_return = None
114
+ for child in body:
115
+ for sub in child:
116
+ if sub.tag.endswith("loginReturn") or sub.tag.endswith("out"):
117
+ login_return = sub
118
+ break
119
+
120
+ if login_return is None:
121
+ return OAAuthResult(success=False, error="响应缺少 loginReturn")
122
+
123
+ session_id = login_return.text
124
+
125
+ if not session_id:
126
+ return OAAuthResult(success=False, error="登录返回空 session")
127
+
128
+ SYLogger.info(f"[OA] 用户 {self.config.login_id} 登录成功")
129
+ return OAAuthResult(
130
+ success=True,
131
+ user=OAUser(session_id=session_id, login_id=self.config.login_id),
132
+ )
133
+
134
+ async def login(self, login_id: Optional[str] = None,
135
+ password: Optional[str] = None) -> OAAuthResult:
136
+ """执行 OA 登录
137
+
138
+ Args:
139
+ login_id: 登录账号(可选,默认使用配置中的账号)
140
+ password: 登录密码(可选,默认使用配置中的密码)
141
+
142
+ Returns:
143
+ OAAuthResult: 登录结果
144
+ """
145
+ try:
146
+ result = await asyncio.get_event_loop().run_in_executor(
147
+ None,
148
+ self._login_sync,
149
+ login_id,
150
+ password,
151
+ )
152
+ return result
153
+ except Exception as e:
154
+ SYLogger.error(f"[OA] 登录异常: {e}")
155
+ return OAAuthResult(success=False, error=str(e))
156
+
157
+ def _login_sync(self, login_id: Optional[str],
158
+ password: Optional[str]) -> OAAuthResult:
159
+ """同步执行 OA 登录"""
160
+ import urllib.request
161
+ import urllib.error
162
+
163
+ soap_xml = self._build_login_xml(login_id, password)
164
+
165
+ headers = {
166
+ "Content-Type": "text/xml; charset=UTF-8",
167
+ "SOAPAction": "",
168
+ }
169
+
170
+ req = urllib.request.Request(
171
+ self.config.doc_service_url,
172
+ data=soap_xml.encode("utf-8"),
173
+ headers=headers,
174
+ method="POST",
175
+ )
176
+
177
+ try:
178
+ # 禁用 SSL 验证(OA 可能使用自签名证书)
179
+ import ssl
180
+ ctx = ssl.create_default_context()
181
+ ctx.check_hostname = False
182
+ ctx.verify_mode = ssl.CERT_NONE
183
+
184
+ with urllib.request.urlopen(req, context=ctx, timeout=15) as resp:
185
+ response_text = resp.read().decode("utf-8")
186
+
187
+ return self._parse_login_response(response_text)
188
+
189
+ except urllib.error.HTTPError as e:
190
+ body = e.read().decode("utf-8", errors="replace")
191
+ SYLogger.error(f"[OA] HTTP 错误 {e.code}: {body[:500]}")
192
+ return OAAuthResult(
193
+ success=False,
194
+ error=f"HTTP {e.code}: {body[:200]}",
195
+ )
196
+ except urllib.error.URLError as e:
197
+ SYLogger.error(f"[OA] 连接失败: {e.reason}")
198
+ return OAAuthResult(success=False, error=f"连接失败: {e.reason}")
199
+ except Exception as e:
200
+ SYLogger.error(f"[OA] 登录请求异常: {e}")
201
+ return OAAuthResult(success=False, error=str(e))