vis-agent 0.2.44.dev7650__tar.gz → 0.2.46.dev7677__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 (138) hide show
  1. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/PKG-INFO +2 -1
  2. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/config.json +9 -0
  3. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/pyproject.toml +4 -1
  4. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/_outside.py +6 -0
  5. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/extension.py +17 -0
  6. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_outside.py +5 -0
  7. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/.gitignore +0 -0
  8. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/LICENSE +0 -0
  9. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/README.md +0 -0
  10. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-arguments.json +0 -0
  11. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-cases.json +0 -0
  12. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-copy.json +0 -0
  13. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-execution.json +0 -0
  14. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-groups.json +0 -0
  15. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-read-session.json +0 -0
  16. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-reads.json +0 -0
  17. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-results.json +0 -0
  18. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity-tables.json +0 -0
  19. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/activity.json +0 -0
  20. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/diff.json +0 -0
  21. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/live-primitives.json +0 -0
  22. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/session-health.json +0 -0
  23. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/fixtures/view.json +0 -0
  24. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/activity.json +0 -0
  25. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/agents.json +0 -0
  26. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/automations.json +0 -0
  27. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/common.json +0 -0
  28. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/content.json +0 -0
  29. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/council.json +0 -0
  30. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/diff.json +0 -0
  31. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/evals.json +0 -0
  32. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/gateway.json +0 -0
  33. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/improve.json +0 -0
  34. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/provider.json +0 -0
  35. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/rooms.json +0 -0
  36. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/symbol.json +0 -0
  37. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/toggle.json +0 -0
  38. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/contracts/schema/view.json +0 -0
  39. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/examples/greeter/tests/test_greeter.py +0 -0
  40. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/hatch_build.py +0 -0
  41. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/__init__.py +0 -0
  42. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/_contracts.py +0 -0
  43. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/_wire.py +0 -0
  44. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/activity.py +0 -0
  45. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/__init__.py +0 -0
  46. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_agent.py +0 -0
  47. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_agents.py +0 -0
  48. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_client.py +0 -0
  49. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_council.py +0 -0
  50. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_extensions.py +0 -0
  51. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/engine/_local.py +0 -0
  52. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/__init__.py +0 -0
  53. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/_gateway.py +0 -0
  54. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/agent.py +0 -0
  55. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/bench.py +0 -0
  56. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/check.py +0 -0
  57. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/compare.py +0 -0
  58. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/environment.py +0 -0
  59. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/grade.py +0 -0
  60. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/harbor.py +0 -0
  61. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/judge-rubric.toml +0 -0
  62. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/judge.py +0 -0
  63. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/labels.py +0 -0
  64. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/leaderboard.py +0 -0
  65. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/repeats.py +0 -0
  66. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/rounds.py +0 -0
  67. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/stages.py +0 -0
  68. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/stats.py +0 -0
  69. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/evals/trajectory.py +0 -0
  70. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/extension_package.py +0 -0
  71. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/py.typed +0 -0
  72. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/rooms.py +0 -0
  73. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/src/blockether/vis/views.py +0 -0
  74. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/conftest.py +0 -0
  75. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/evals_atif.py +0 -0
  76. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_activity.py +0 -0
  77. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_agent.py +0 -0
  78. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_agent_extension_lifecycle.py +0 -0
  79. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_agent_extensions.py +0 -0
  80. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_agents.py +0 -0
  81. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_api_guides.py +0 -0
  82. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_attachments.py +0 -0
  83. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_authoring.py +0 -0
  84. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_catalog.py +0 -0
  85. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_catalog_recipe.py +0 -0
  86. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_ci_report_recipe.py +0 -0
  87. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_client.py +0 -0
  88. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_client_extensions_engine.py +0 -0
  89. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_code_quality_recipe.py +0 -0
  90. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_contracts.py +0 -0
  91. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_council.py +0 -0
  92. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_declarations.py +0 -0
  93. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_engine.py +0 -0
  94. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_engine_docstrings.py +0 -0
  95. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_agent.py +0 -0
  96. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_bench.py +0 -0
  97. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_check.py +0 -0
  98. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_compare.py +0 -0
  99. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_environment.py +0 -0
  100. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_gateway.py +0 -0
  101. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_grade.py +0 -0
  102. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_guards.py +0 -0
  103. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_harbor.py +0 -0
  104. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_judge.py +0 -0
  105. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_labels.py +0 -0
  106. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_repeats.py +0 -0
  107. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_rounds.py +0 -0
  108. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_stages.py +0 -0
  109. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_stats.py +0 -0
  110. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_tasks.py +0 -0
  111. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_evals_trajectory.py +0 -0
  112. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_extension_package.py +0 -0
  113. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_extension_reference.py +0 -0
  114. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_gateway_performance.py +0 -0
  115. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_goals.py +0 -0
  116. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_live_primitives.py +0 -0
  117. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_live_wait.py +0 -0
  118. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_local.py +0 -0
  119. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_method_typing.py +0 -0
  120. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_monitor_recipe.py +0 -0
  121. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_namespace.py +0 -0
  122. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_providers.py +0 -0
  123. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_read_session.py +0 -0
  124. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_record_arguments.py +0 -0
  125. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_registration.py +0 -0
  126. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_repair_hooks.py +0 -0
  127. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_result_sequence.py +0 -0
  128. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_rooms.py +0 -0
  129. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_scoped_settings.py +0 -0
  130. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_sdk_bootstrap.py +0 -0
  131. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_sdk_guide.py +0 -0
  132. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_sdk_typing.py +0 -0
  133. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_structured_live.py +0 -0
  134. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_symbol_contract.py +0 -0
  135. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_testing.py +0 -0
  136. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_text_list_arguments.py +0 -0
  137. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_tools.py +0 -0
  138. {vis_agent-0.2.44.dev7650 → vis_agent-0.2.46.dev7677}/tests/test_views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vis-agent
3
- Version: 0.2.44.dev7650
3
+ Version: 0.2.46.dev7677
4
4
  Summary: The Vis Python SDK — author extensions and control local or remote engines.
5
5
  Project-URL: Homepage, https://vis.blockether.com
6
6
  Project-URL: Documentation, https://vis.blockether.com
@@ -18,6 +18,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
18
  Requires-Python: >=3.12
19
19
  Requires-Dist: harbor==0.24.0
20
20
  Requires-Dist: jsonschema<5,>=4.23
21
+ Requires-Dist: litellm==1.103.1
21
22
  Requires-Dist: packaging>=24
22
23
  Requires-Dist: pydantic<3,>=2.13.5
23
24
  Requires-Dist: referencing>=0.28.4
@@ -823,6 +823,15 @@
823
823
  "pattern": "^https?://[^\\s/?#@]+(?:/[^\\s?#@]*)?$",
824
824
  "description": "Primary index for Vis-managed pip installs and the default index for uv CLI and project preparation. Explicit uv index environment settings and --default-index take precedence. Credentials, query strings and fragments are not accepted; configure authentication outside committed YAML."
825
825
  },
826
+ "environment": {
827
+ "type": "string",
828
+ "enum": [
829
+ "project",
830
+ "shared"
831
+ ],
832
+ "default": "project",
833
+ "description": "Environment for project Python: the uv projects of project extensions inside the project tree and the Python language tools. project uses each project's own environment, normally .venv. shared prepares extension projects like vis-agent python --shared uv sync, loads them from Vis shared packages and runs the Python language tools with vis-agent python --shared."
834
+ },
826
835
  "source_paths": {
827
836
  "type": "array",
828
837
  "items": {
@@ -8,16 +8,19 @@ build-backend = "hatchling.build"
8
8
 
9
9
  [project]
10
10
  name = "vis-agent"
11
- version = "0.2.44.dev7650"
11
+ version = "0.2.46.dev7677"
12
12
  description = "The Vis Python SDK — author extensions and control local or remote engines."
13
13
  readme = "README.md"
14
14
  requires-python = ">=3.12"
15
15
  license = "Apache-2.0"
16
16
  license-files = ["LICENSE"]
17
17
  # Harbor runs the tasks of `blockether.vis.evals`: the agent, host environment, check and judge.
18
+ # Keep LiteLLM at this exact version: some corporate Artifactory mirrors serve only this build.
19
+ # Harbor accepts it (`litellm>=1.92.0`).
18
20
  dependencies = [
19
21
  "harbor==0.24.0",
20
22
  "jsonschema>=4.23,<5",
23
+ "litellm==1.103.1",
21
24
  "packaging>=24",
22
25
  "pydantic>=2.13.5,<3",
23
26
  "referencing>=0.28.4",
@@ -106,6 +106,11 @@ def workspace_root():
106
106
  return str(Path.cwd())
107
107
 
108
108
 
109
+ def python_environment():
110
+ """Use the project environment when no Vis session owns this call."""
111
+ return "project"
112
+
113
+
109
114
  def setting_declaration(spec):
110
115
  """Use the package's own JSON Schemas for outside-host declarations."""
111
116
  from ._contracts import definition, problems, validate
@@ -1431,6 +1436,7 @@ def _live_handle(held, envelope, op, view_id):
1431
1436
 
1432
1437
  _IMPLEMENTATIONS = {
1433
1438
  "workspace_root": workspace_root,
1439
+ "python_environment": python_environment,
1434
1440
  "setting_declaration": setting_declaration,
1435
1441
  "setting": setting,
1436
1442
  "state_get": state_get,
@@ -57,6 +57,10 @@ class Host(Protocol):
57
57
  """Read the active session working copy, or the outside process directory."""
58
58
  ...
59
59
 
60
+ def python_environment(self) -> str:
61
+ """Read the project's `python.environment`: `project` or `shared`."""
62
+ ...
63
+
60
64
  def setting_declaration(self, spec: Mapping[str, Any]) -> Mapping[str, Any]:
61
65
  """Validate a declaration and fill defaults from the contract schema."""
62
66
  ...
@@ -3341,6 +3345,19 @@ def workspace_root() -> Path:
3341
3345
  return Path(_host.workspace_root())
3342
3346
 
3343
3347
 
3348
+ def python_environment() -> Literal["project", "shared"]:
3349
+ """Return the Python environment that the session's project selects.
3350
+
3351
+ The value comes from `python.environment` in the merged configuration.
3352
+ `shared` means that project Python runs like `vis-agent python --shared`,
3353
+ with Vis shared packages and without the project's `.venv`. `project`, the
3354
+ default, means that the project's own environment applies. Outside Vis, the
3355
+ value is `project`.
3356
+ """
3357
+ value = _host.python_environment()
3358
+ return "shared" if value == "shared" else "project"
3359
+
3360
+
3344
3361
  def log(level, msg):
3345
3362
  _host.log(str(level), str(msg))
3346
3363
 
@@ -105,6 +105,11 @@ def test_workspace_root_tracks_outside_process_directory(tmp_path, monkeypatch):
105
105
  assert isinstance(vis.workspace_root(), Path)
106
106
 
107
107
 
108
+ def test_python_environment_defaults_to_project_outside_vis():
109
+ # Regression, #379: py tools read this value to choose the shared interpreter.
110
+ assert vis.python_environment() == "project"
111
+
112
+
108
113
  @pytest.mark.parametrize("name", ["jailed_shell", "council_wake"])
109
114
  def test_session_bound_operations_refuse_without_the_host(name):
110
115
  with pytest.raises(_outside.Refused, match=f"vis\\.{name}"):