norpagent 2.2.1__tar.gz → 2.2.2__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 (176) hide show
  1. {norpagent-2.2.1 → norpagent-2.2.2}/PKG-INFO +7 -5
  2. {norpagent-2.2.1 → norpagent-2.2.2}/README.md +2 -1
  3. {norpagent-2.2.1 → norpagent-2.2.2}/pyproject.toml +5 -4
  4. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_cnb_whitebox.py +4 -4
  5. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/__init__.py +17 -1
  6. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sessions/memory.py +14 -0
  7. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sessions/sqlite.py +26 -2
  8. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/ask_user.py +3 -1
  9. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/assets/front.html +518 -61
  10. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/console.py +5 -2
  11. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/multimodal.py +1 -1
  12. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/web.py +201 -7
  13. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/__init__.py +1 -1
  14. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/cortex.py +70 -70
  15. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/node.py +48 -6
  16. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/tree.py +53 -53
  17. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/frontends/web.py +15 -1
  18. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/agent.py +9 -4
  19. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/context.py +15 -3
  20. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/nasyncio.py +1 -1
  21. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/session.py +15 -0
  22. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/ui.py +7 -2
  23. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/recovery/__init__.py +1 -1
  24. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/approval.py +7 -3
  25. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/settings.py +35 -0
  26. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/PKG-INFO +7 -5
  27. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_minimal_kernel_suite.py +1 -1
  28. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round15_suite.py +8 -8
  29. {norpagent-2.2.1 → norpagent-2.2.2}/LICENSE +0 -0
  30. {norpagent-2.2.1 → norpagent-2.2.2}/setup.cfg +0 -0
  31. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/__init__.py +0 -0
  32. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/cli.py +0 -0
  33. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/demo.py +0 -0
  34. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_cnb.py +0 -0
  35. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_cnb_slots.py +0 -0
  36. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_cnb_v200.py +0 -0
  37. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_deep_tree.py +0 -0
  38. {norpagent-2.2.1 → norpagent-2.2.2}/src/nervous_bus/test_e2e.py +0 -0
  39. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/__main__.py +0 -0
  40. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/arch/__init__.py +0 -0
  41. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/arch/address.py +0 -0
  42. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/arch/layer.py +0 -0
  43. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/arch/slots.py +0 -0
  44. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/__init__.py +0 -0
  45. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/context/__init__.py +0 -0
  46. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/context/fts5.py +0 -0
  47. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/models/__init__.py +0 -0
  48. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/models/anthropic.py +0 -0
  49. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/models/mock.py +0 -0
  50. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/models/openai_compat.py +0 -0
  51. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/projects/__init__.py +0 -0
  52. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/projects/basic.py +0 -0
  53. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sandboxes/__init__.py +0 -0
  54. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sandboxes/isolated_python.py +0 -0
  55. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sandboxes/pooled.py +0 -0
  56. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sandboxes/subprocess.py +0 -0
  57. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/scheduler/__init__.py +0 -0
  58. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/scheduler/persistent.py +0 -0
  59. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/scheduler/simple.py +0 -0
  60. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/sessions/__init__.py +0 -0
  61. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/__init__.py +0 -0
  62. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/clock.py +0 -0
  63. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/context_tools.py +0 -0
  64. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/echo.py +0 -0
  65. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/exec_cmd.py +0 -0
  66. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/file_io.py +0 -0
  67. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/file_surgeon.py +0 -0
  68. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/pathsafe.py +0 -0
  69. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/project_tools.py +0 -0
  70. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/run_python.py +0 -0
  71. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/search_in_file.py +0 -0
  72. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/task_tools.py +0 -0
  73. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/tools/web.py +0 -0
  74. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/__init__.py +0 -0
  75. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/assets/norp-farstars.html +0 -0
  76. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/builtin/ui/assets/norp-flow.html +0 -0
  77. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cli.py +0 -0
  78. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/bus.py +0 -0
  79. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/cli.py +0 -0
  80. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/demo.py +0 -0
  81. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/engine.py +0 -0
  82. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/permissions.py +0 -0
  83. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/protocol.py +0 -0
  84. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/slots.py +0 -0
  85. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/cnb/topology.py +0 -0
  86. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/core.py +0 -0
  87. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/__init__.py +0 -0
  88. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/engines.py +0 -0
  89. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/hotswap.py +0 -0
  90. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/packages.py +0 -0
  91. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/points.py +0 -0
  92. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/proposals.py +0 -0
  93. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/rhythm.py +0 -0
  94. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/evolution/store.py +0 -0
  95. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/farstars_app/__init__.py +0 -0
  96. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/farstars_app/entry.py +0 -0
  97. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/flows/__init__.py +0 -0
  98. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/frontends/__init__.py +0 -0
  99. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/frontends/base.py +0 -0
  100. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/frontends/console.py +0 -0
  101. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/frontends/headless.py +0 -0
  102. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/hooks/__init__.py +0 -0
  103. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/hooks/core.py +0 -0
  104. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/hooks/standard.py +0 -0
  105. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/__init__.py +0 -0
  106. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/events.py +0 -0
  107. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/presets.py +0 -0
  108. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/kernel/registry.py +0 -0
  109. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/loops/__init__.py +0 -0
  110. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/loops/base.py +0 -0
  111. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/loops/cancel.py +0 -0
  112. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/loops/nasyncio.py +0 -0
  113. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/loops/std_asyncio.py +0 -0
  114. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/__init__.py +0 -0
  115. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/creative.py +0 -0
  116. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/embedded.py +0 -0
  117. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/longrun.py +0 -0
  118. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/minimal.py +0 -0
  119. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/ptc.py +0 -0
  120. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/modes/standard.py +0 -0
  121. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/plugins/__init__.py +0 -0
  122. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/plugins/host.py +0 -0
  123. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/plugins/isolation.py +0 -0
  124. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/plugins/loader.py +0 -0
  125. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/plugins/manager.py +0 -0
  126. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/__init__.py +0 -0
  127. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/model.py +0 -0
  128. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/plugin.py +0 -0
  129. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/sandbox.py +0 -0
  130. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/scheduler.py +0 -0
  131. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/protocols/tool.py +0 -0
  132. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/py.typed +0 -0
  133. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/recovery/capture.py +0 -0
  134. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/recovery/store.py +0 -0
  135. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/rescue.py +0 -0
  136. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/rescue_api.py +0 -0
  137. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/runtime/__init__.py +0 -0
  138. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/runtime/cnb.py +0 -0
  139. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/runtime/engine.py +0 -0
  140. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/runtime/mount.py +0 -0
  141. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/runtime/remount.py +0 -0
  142. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/safe.py +0 -0
  143. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/__init__.py +0 -0
  144. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/audit.py +0 -0
  145. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/guard.py +0 -0
  146. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/network_policy.py +0 -0
  147. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/security/signature.py +0 -0
  148. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/settings_cli.py +0 -0
  149. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/unbox.py +0 -0
  150. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent/whitebox.py +0 -0
  151. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/SOURCES.txt +0 -0
  152. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/dependency_links.txt +0 -0
  153. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/entry_points.txt +0 -0
  154. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/requires.txt +0 -0
  155. {norpagent-2.2.1 → norpagent-2.2.2}/src/norpagent.egg-info/top_level.txt +0 -0
  156. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_cnb_automount.py +0 -0
  157. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_cnb_kernel_actions.py +0 -0
  158. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_cnb_tree_suite.py +0 -0
  159. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_evo_hardening_suite.py +0 -0
  160. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_evolution_suite.py +0 -0
  161. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_lang_model_suite.py +0 -0
  162. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_memory_clear_suite.py +0 -0
  163. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_plugin_suite.py +0 -0
  164. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_render_stats_suite.py +0 -0
  165. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round10_suite.py +0 -0
  166. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round11_suite.py +0 -0
  167. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round12_suite.py +0 -0
  168. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round13_suite.py +0 -0
  169. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round14_suite.py +0 -0
  170. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round17_suite.py +0 -0
  171. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round18_suite.py +0 -0
  172. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round19_suite.py +0 -0
  173. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round20_suite.py +0 -0
  174. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_round9_suite.py +0 -0
  175. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_ui_feedback_suite.py +0 -0
  176. {norpagent-2.2.1 → norpagent-2.2.2}/test/test_v22_suite.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: norpagent
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Summary: FarStars(远星)· norpagent — pluggable component-based agent framework: modular architecture layers with address functions, np() single-call startup, 9 layers / 29 hooks, norpagent.safe() decoupled security, process-level plugin isolation, ready-to-use preset modes, Central Nervous Bus (CNB) multi-instance neural tree (cortex control / freeze quarantine / subpoena evidence / behavior baselines)
5
5
  Author: xingluosama121
6
6
  License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/xingluosama121/norp-agent
8
- Project-URL: Documentation, https://github.com/xingluosama121/norp-agent/tree/main/docs
9
- Project-URL: Issues, https://github.com/xingluosama121/norp-agent/issues
7
+ Project-URL: Homepage, https://github.com/xingluosama121/farstars2
8
+ Project-URL: Documentation, https://github.com/xingluosama121/farstars2/tree/main/docs
9
+ Project-URL: Issues, https://github.com/xingluosama121/farstars2/issues
10
+ Project-URL: PyPI, https://pypi.org/project/norpagent/
10
11
  Keywords: agent,plugin,llm,framework,multi-agent,sandbox,hooks,security,context,farstars,远星,cnb,neural-bus,subpoena
11
12
  Classifier: Development Status :: 4 - Beta
12
13
  Classifier: Intended Audience :: Developers
@@ -51,8 +52,9 @@ Dynamic: license-file
51
52
 
52
53
  A pluggable, brick-style Agent framework — *the module is the entry point*. Build an Agent the way you build with LEGO: swap any part by filling in an "address", with zero changes to the core code — and swap parts while the process is still running (hot mount), with no restart required.
53
54
 
54
- > **Version**: 2.2.1 (2026-09-12) | **Brand**: FarStars(远星)— the official public name since v2.0.0; the package, imports and PyPI name stay `norpagent` | **License**: Copyright (c) 2026 xingluosama121, MIT Licensed
55
+ > **Version**: 2.2.2 (2026-09-13) | **Brand**: FarStars(远星)— the official public name since v2.0.0; the package, imports and PyPI name stay `norpagent` | **License**: Copyright (c) 2026 xingluosama121, MIT Licensed
55
56
  > **Dependencies**: the core package has **zero third-party dependencies** — a plain Python standard library is enough to run it; optional capabilities are installed on demand
57
+ > **Repository**: https://github.com/xingluosama121/farstars2 | **PyPI**: https://pypi.org/project/norpagent/
56
58
 
57
59
  ---
58
60
 
@@ -2,8 +2,9 @@
2
2
 
3
3
  A pluggable, brick-style Agent framework — *the module is the entry point*. Build an Agent the way you build with LEGO: swap any part by filling in an "address", with zero changes to the core code — and swap parts while the process is still running (hot mount), with no restart required.
4
4
 
5
- > **Version**: 2.2.1 (2026-09-12) | **Brand**: FarStars(远星)— the official public name since v2.0.0; the package, imports and PyPI name stay `norpagent` | **License**: Copyright (c) 2026 xingluosama121, MIT Licensed
5
+ > **Version**: 2.2.2 (2026-09-13) | **Brand**: FarStars(远星)— the official public name since v2.0.0; the package, imports and PyPI name stay `norpagent` | **License**: Copyright (c) 2026 xingluosama121, MIT Licensed
6
6
  > **Dependencies**: the core package has **zero third-party dependencies** — a plain Python standard library is enough to run it; optional capabilities are installed on demand
7
+ > **Repository**: https://github.com/xingluosama121/farstars2 | **PyPI**: https://pypi.org/project/norpagent/
7
8
 
8
9
  ---
9
10
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "norpagent"
8
- version = "2.2.1"
8
+ version = "2.2.2"
9
9
  # FarStars(远星)是 norpagent 自 v2.0.0 起的正式宣传名:调用方式与内核
10
10
  # 名称不变(import norpagent / PyPI 包名 norpagent 保持不变),远星 FarStars
11
11
  # 为对外品牌冠名。
@@ -35,9 +35,10 @@ classifiers = [
35
35
  dependencies = []
36
36
 
37
37
  [project.urls]
38
- Homepage = "https://github.com/xingluosama121/norp-agent"
39
- Documentation = "https://github.com/xingluosama121/norp-agent/tree/main/docs"
40
- Issues = "https://github.com/xingluosama121/norp-agent/issues"
38
+ Homepage = "https://github.com/xingluosama121/farstars2"
39
+ Documentation = "https://github.com/xingluosama121/farstars2/tree/main/docs"
40
+ Issues = "https://github.com/xingluosama121/farstars2/issues"
41
+ PyPI = "https://pypi.org/project/norpagent/"
41
42
 
42
43
  [project.optional-dependencies]
43
44
  # Model adapter for OpenAI-compatible services (DeepSeek / OpenAI / Qwen / vLLM / Ollama, etc.)
@@ -457,10 +457,10 @@ def main():
457
457
  check("W605 节流审计:同类型 30s 窗口内只记首条",
458
458
  cnt == 1, f"count={cnt}")
459
459
 
460
- # ── 版本号(2.2.1:缺陷收口专项)──
461
- print("\n── 版本号 2.2.1 ──")
462
- check("W-ver 版本号为 2.2.1",
463
- norpagent.__version__ == "2.2.1", norpagent.__version__)
460
+ # ── 版本号(2.2.2:设置治理 / 安全可关闭 / 主题系统专项)──
461
+ print("\n── 版本号 2.2.2 ──")
462
+ check("W-ver 版本号为 2.2.2",
463
+ norpagent.__version__ == "2.2.2", norpagent.__version__)
464
464
 
465
465
  # ── 清理 ──
466
466
  node2.stop()
@@ -217,7 +217,23 @@ from norpagent import farstars_app # noqa: E402,F401
217
217
  # (raw markdown / LaTeX 源码 + 提示词)估算 input + output(此前只算渲染后
218
218
  # 的可见输出且缺 input,导致总 token 偏低);估算值带 estimated 标记,前端
219
219
  # 以「≈」如实标注,端点回传 usage 时依旧以服务端数值为准。
220
- __version__ = "2.2.1"
220
+ # v2.2.2(2026-09-13)设置治理 / 安全可关闭 / 主题系统 / 前端修复 / 索引合并:
221
+ # - 设置项治理:灰化项逐个核实后端功能——确有功能且已接入运行态者重新启用
222
+ # (security.level / model.top_p / model.call_timeout / runtime.snapshot_dir),
223
+ # 无实现或由面板外机制控制者隐藏入口(HIDDEN_KEYS;仍登记于设置库保留审计);
224
+ # - 安全系统「默认常开」项(security.enabled / safe_enabled / signature_verify)
225
+ # 去 locked 灰化、标 danger:允许关闭,前端关闭前弹不可点击外部 / ESC 关闭的
226
+ # 强制确认框;后端尊重开关(不再硬编码 True);
227
+ # - 安全拦截告警常驻(取消自动消失)+ 同源聚合 + 一键清除;
228
+ # - 主题系统:ui.theme 单一 JSON 文档(mode / active / themes)+ 主题设计器 +
229
+ # 内置预设与自定义主题(配色令牌 / 圆角字体 / 可选高级 CSS 校验)+ 导出 / 导入
230
+ # JSON 与 Markdown + localStorage 与设置库双镜像;
231
+ # - 界面语言收敛为 zh_CN / en(zh_TW 下线、历史值归一 zh_CN);设置面板「界面
232
+ # 语言」与顶栏语言按钮共用 np_lang 与设置库键 ui.language,两处同步;
233
+ # - 前端修复:ask_user 模态 Enter 发送 + Markdown 渲染;思考过程块可自由滚动;
234
+ # - 索引存储合并:workspace_index.db / context_index.db 合并为 unified_index.py
235
+ # 单库单连接 + 统一维护,workspace_index.py / context_index.py 降为兼容转发层。
236
+ __version__ = "2.2.2"
221
237
  __brand_cn__ = "远星"
222
238
  __brand_en__ = "FarStars"
223
239
  __display_name__ = "FarStars(远星)· norpagent"
@@ -99,6 +99,20 @@ class MemorySessionManager:
99
99
  sess.pinned = bool(pinned)
100
100
  return True
101
101
 
102
+ def set_system_prompt(self, session_id: str, prompt: str,
103
+ mode: str = "append") -> bool:
104
+ """Store the per-session system prompt (2026-09-13)."""
105
+ with self._lock:
106
+ sess = self._sessions.get(session_id)
107
+ if sess is None:
108
+ return False
109
+ sess.system_prompt = str(prompt or "")
110
+ sess.system_prompt_mode = (
111
+ "replace" if str(mode or "").strip().lower() == "replace"
112
+ else "append"
113
+ )
114
+ return True
115
+
102
116
  def delete_session(self, session_id: str) -> bool:
103
117
  with self._lock:
104
118
  return self._sessions.pop(session_id, None) is not None
@@ -33,7 +33,9 @@ CREATE TABLE IF NOT EXISTS sessions (
33
33
  title TEXT NOT NULL DEFAULT '',
34
34
  created_at REAL NOT NULL,
35
35
  updated_at REAL NOT NULL DEFAULT 0,
36
- pinned INTEGER NOT NULL DEFAULT 0
36
+ pinned INTEGER NOT NULL DEFAULT 0,
37
+ system_prompt TEXT NOT NULL DEFAULT '',
38
+ system_prompt_mode TEXT NOT NULL DEFAULT 'append'
37
39
  );
38
40
  CREATE TABLE IF NOT EXISTS messages (
39
41
  seq INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -62,6 +64,9 @@ _SESSION_MIGRATIONS = (
62
64
  ("updated_at", "REAL NOT NULL DEFAULT 0"),
63
65
  # 2026-09-12 round 9: pinned to the top of the session list
64
66
  ("pinned", "INTEGER NOT NULL DEFAULT 0"),
67
+ # 2026-09-13: per-session system prompt (append / replace the global base)
68
+ ("system_prompt", "TEXT NOT NULL DEFAULT ''"),
69
+ ("system_prompt_mode", "TEXT NOT NULL DEFAULT 'append'"),
65
70
  )
66
71
 
67
72
  # legacy database migration: early messages tables lack the reasoning / attachments columns
@@ -274,7 +279,8 @@ class SQLiteSessionManager:
274
279
  def get_session(self, session_id: str) -> Optional[Session]:
275
280
  with self._lock:
276
281
  row = self._conn.execute(
277
- "SELECT id, title, created_at, updated_at, pinned FROM sessions"
282
+ "SELECT id, title, created_at, updated_at, pinned,"
283
+ " system_prompt, system_prompt_mode FROM sessions"
278
284
  " WHERE id = ?",
279
285
  (session_id,),
280
286
  ).fetchone()
@@ -286,6 +292,8 @@ class SQLiteSessionManager:
286
292
  messages=messages,
287
293
  updated_at=(row["updated_at"] or row["created_at"]),
288
294
  pinned=bool(row["pinned"]),
295
+ system_prompt=row["system_prompt"] or "",
296
+ system_prompt_mode=(row["system_prompt_mode"] or "append"),
289
297
  )
290
298
 
291
299
  def append_message(self, session_id: str, message: ChatMessage) -> bool:
@@ -350,6 +358,22 @@ class SQLiteSessionManager:
350
358
  self._conn.commit()
351
359
  return cur.rowcount > 0
352
360
 
361
+ def set_system_prompt(self, session_id: str, prompt: str,
362
+ mode: str = "append") -> bool:
363
+ """Store the per-session system prompt (persisted; 2026-09-13)."""
364
+ normalized = (
365
+ "replace" if str(mode or "").strip().lower() == "replace"
366
+ else "append"
367
+ )
368
+ with self._lock:
369
+ cur = self._conn.execute(
370
+ "UPDATE sessions SET system_prompt = ?, system_prompt_mode = ?"
371
+ " WHERE id = ?",
372
+ (str(prompt or ""), normalized, session_id),
373
+ )
374
+ self._conn.commit()
375
+ return cur.rowcount > 0
376
+
353
377
  def delete_session(self, session_id: str) -> bool:
354
378
  with self._lock:
355
379
  cur = self._conn.execute("DELETE FROM sessions WHERE id = ?", (session_id,))
@@ -71,7 +71,9 @@ class AskUserTool:
71
71
  )
72
72
  answer = ""
73
73
  try:
74
- answer = ctx.ask_user(question, default)
74
+ # kind="clarify": this is an open question, so the UI keeps its text box
75
+ # (only approval prompts switch to reject/approve buttons).
76
+ answer = ctx.ask_user(question, default, kind="clarify")
75
77
  except Exception as exc: # noqa: BLE001 — never let interaction break the task
76
78
  return ToolResult(
77
79
  output=(