vis-agent 0.3.3.dev7975__tar.gz → 0.3.4.dev8033__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 (156) hide show
  1. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/.gitignore +3 -0
  2. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/PKG-INFO +1 -1
  3. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/agents.json +97 -1
  4. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/config.json +29 -0
  5. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/evals.json +8 -1
  6. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/gateway.json +25 -1
  7. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/toggle.json +67 -2
  8. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/pyproject.toml +1 -1
  9. vis_agent-0.3.4.dev8033/release-tag +1 -0
  10. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/__init__.py +2 -1
  11. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_agent.py +8 -2
  12. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_agents.py +6 -0
  13. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_council.py +30 -6
  14. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/__init__.py +38 -2
  15. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/agent.py +133 -13
  16. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/bench.py +3 -2
  17. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/environment.py +1 -1
  18. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/grade.py +35 -0
  19. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/harbor.py +63 -6
  20. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/labels.py +54 -8
  21. vis_agent-0.3.4.dev8033/src/blockether/vis/evals/lic.py +277 -0
  22. vis_agent-0.3.4.dev8033/src/blockether/vis/evals/longmemeval.py +413 -0
  23. vis_agent-0.3.4.dev8033/src/blockether/vis/evals/mrcr.py +273 -0
  24. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/repeats.py +33 -13
  25. vis_agent-0.3.4.dev8033/src/blockether/vis/evals/report.py +60 -0
  26. vis_agent-0.3.4.dev8033/src/blockether/vis/evals/reports.py +246 -0
  27. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/stages.py +18 -2
  28. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/stats.py +79 -3
  29. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/trajectory.py +57 -0
  30. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/extension.py +12 -2
  31. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_agent.py +12 -0
  32. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_agents.py +7 -2
  33. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_client.py +6 -1
  34. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_contracts.py +3 -3
  35. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_agent.py +53 -5
  36. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_environment.py +13 -0
  37. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_grade.py +20 -0
  38. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_labels.py +38 -0
  39. vis_agent-0.3.4.dev8033/tests/test_evals_lic.py +114 -0
  40. vis_agent-0.3.4.dev8033/tests/test_evals_longmemeval.py +136 -0
  41. vis_agent-0.3.4.dev8033/tests/test_evals_mrcr.py +101 -0
  42. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_repeats.py +21 -0
  43. vis_agent-0.3.4.dev8033/tests/test_evals_report.py +127 -0
  44. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_stages.py +5 -0
  45. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_stats.py +84 -1
  46. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_tasks.py +80 -1
  47. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_trajectory.py +31 -0
  48. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_scoped_settings.py +32 -0
  49. vis_agent-0.3.3.dev7975/release-tag +0 -1
  50. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/LICENSE +0 -0
  51. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/README.md +0 -0
  52. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-arguments.json +0 -0
  53. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-cases.json +0 -0
  54. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-copy.json +0 -0
  55. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-execution.json +0 -0
  56. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-groups.json +0 -0
  57. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-read-session.json +0 -0
  58. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-reads.json +0 -0
  59. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-results.json +0 -0
  60. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-stream.json +0 -0
  61. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity-tables.json +0 -0
  62. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/activity.json +0 -0
  63. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/diff.json +0 -0
  64. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/live-primitives.json +0 -0
  65. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/session-health.json +0 -0
  66. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/fixtures/view.json +0 -0
  67. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/activity.json +0 -0
  68. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/automations.json +0 -0
  69. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/common.json +0 -0
  70. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/content.json +0 -0
  71. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/council.json +0 -0
  72. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/diff.json +0 -0
  73. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/improve.json +0 -0
  74. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/provider.json +0 -0
  75. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/rooms.json +0 -0
  76. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/symbol.json +0 -0
  77. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/contracts/schema/view.json +0 -0
  78. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/examples/greeter/tests/test_greeter.py +0 -0
  79. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/hatch_build.py +0 -0
  80. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/__init__.py +0 -0
  81. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/_contracts.py +0 -0
  82. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/_outside.py +0 -0
  83. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/_wire.py +0 -0
  84. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/activity.py +0 -0
  85. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_client.py +0 -0
  86. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_extensions.py +0 -0
  87. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_host.py +0 -0
  88. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_install.py +0 -0
  89. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_local.py +0 -0
  90. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/engine/_models.py +0 -0
  91. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/_gateway.py +0 -0
  92. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/check.py +0 -0
  93. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/compare.py +0 -0
  94. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/judge-rubric.toml +0 -0
  95. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/judge.py +0 -0
  96. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/leaderboard.py +0 -0
  97. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/evals/rounds.py +0 -0
  98. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/extension_package.py +0 -0
  99. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/py.typed +0 -0
  100. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/rooms.py +0 -0
  101. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/src/blockether/vis/views.py +0 -0
  102. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/conftest.py +0 -0
  103. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/evals_atif.py +0 -0
  104. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_activity.py +0 -0
  105. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_agent_extension_lifecycle.py +0 -0
  106. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_agent_extensions.py +0 -0
  107. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_api_guides.py +0 -0
  108. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_attachments.py +0 -0
  109. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_authoring.py +0 -0
  110. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_catalog.py +0 -0
  111. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_catalog_recipe.py +0 -0
  112. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_ci_report_recipe.py +0 -0
  113. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_client_extensions_engine.py +0 -0
  114. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_code_quality_recipe.py +0 -0
  115. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_council.py +0 -0
  116. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_declarations.py +0 -0
  117. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_engine.py +0 -0
  118. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_engine_docstrings.py +0 -0
  119. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_bench.py +0 -0
  120. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_check.py +0 -0
  121. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_compare.py +0 -0
  122. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_gateway.py +0 -0
  123. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_guards.py +0 -0
  124. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_harbor.py +0 -0
  125. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_judge.py +0 -0
  126. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_evals_rounds.py +0 -0
  127. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_extension_package.py +0 -0
  128. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_extension_reference.py +0 -0
  129. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_gateway_performance.py +0 -0
  130. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_goals.py +0 -0
  131. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_install.py +0 -0
  132. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_live_primitives.py +0 -0
  133. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_live_wait.py +0 -0
  134. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_local.py +0 -0
  135. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_method_typing.py +0 -0
  136. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_models.py +0 -0
  137. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_monitor_recipe.py +0 -0
  138. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_namespace.py +0 -0
  139. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_outside.py +0 -0
  140. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_providers.py +0 -0
  141. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_read_session.py +0 -0
  142. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_record_arguments.py +0 -0
  143. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_registration.py +0 -0
  144. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_repair_hooks.py +0 -0
  145. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_result_sequence.py +0 -0
  146. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_rooms.py +0 -0
  147. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_sdk_bootstrap.py +0 -0
  148. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_sdk_guide.py +0 -0
  149. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_sdk_typing.py +0 -0
  150. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_shortcuts_live.py +0 -0
  151. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_structured_live.py +0 -0
  152. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_symbol_contract.py +0 -0
  153. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_testing.py +0 -0
  154. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_text_list_arguments.py +0 -0
  155. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_tools.py +0 -0
  156. {vis_agent-0.3.3.dev7975 → vis_agent-0.3.4.dev8033}/tests/test_views.py +0 -0
@@ -117,3 +117,6 @@ own_your_harness.pptx
117
117
  # Call journal written by the e2e schema-probe fixture when it runs from this
118
118
  # checkout instead of a temporary workspace.
119
119
  /schema-calls.jsonl
120
+
121
+ # uv lockfiles. The SDK and the examples are libraries; uv writes the lock locally.
122
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vis-agent
3
- Version: 0.3.3.dev7975
3
+ Version: 0.3.4.dev8033
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
@@ -15,6 +15,9 @@
15
15
  "maxLength": 8192,
16
16
  "pattern": "\\S"
17
17
  },
18
+ "role": {
19
+ "$ref": "#/$defs/role"
20
+ },
18
21
  "model": {
19
22
  "type": "string",
20
23
  "minLength": 1
@@ -77,6 +80,9 @@
77
80
  "task": {
78
81
  "$ref": "#/$defs/spawn/properties/task"
79
82
  },
83
+ "role": {
84
+ "$ref": "#/$defs/spawn/properties/role"
85
+ },
80
86
  "model": {
81
87
  "$ref": "#/$defs/spawn/properties/model"
82
88
  },
@@ -191,8 +197,29 @@
191
197
  ],
192
198
  "additionalProperties": false
193
199
  },
200
+ "answer": {
201
+ "$comment": "A person answers the open question of a subagent for its parent.",
202
+ "type": "object",
203
+ "properties": {
204
+ "session_id": {
205
+ "type": "string",
206
+ "minLength": 1
207
+ },
208
+ "text": {
209
+ "type": "string",
210
+ "minLength": 1,
211
+ "maxLength": 8192,
212
+ "pattern": "\\S"
213
+ }
214
+ },
215
+ "required": [
216
+ "session_id",
217
+ "text"
218
+ ],
219
+ "additionalProperties": false
220
+ },
194
221
  "grant": {
195
- "$comment": "Add file rules to the grant of a subagent. A child without write rules writes only the granted rules after a write grant.",
222
+ "$comment": "Add file rules to the grant of a subagent. A child without write rules already writes where its parent writes, so a write grant changes nothing for it. A write rule under a read_only or deny rule of the child fails.",
196
223
  "type": "object",
197
224
  "properties": {
198
225
  "session_id": {
@@ -238,6 +265,10 @@
238
265
  "task": {
239
266
  "$ref": "#/$defs/spawn/properties/task"
240
267
  },
268
+ "files": {
269
+ "$comment": "Replace the grant of the child for the follow-up task.",
270
+ "$ref": "#/$defs/files"
271
+ },
241
272
  "timeout_secs": {
242
273
  "$ref": "#/$defs/wait/properties/timeout_secs"
243
274
  }
@@ -270,6 +301,32 @@
270
301
  ],
271
302
  "additionalProperties": false
272
303
  },
304
+ "role": {
305
+ "description": "Choose the role by the result that you need: facts, changed files, a pass or fail, or findings.",
306
+ "$comment": "A role is a label for people and the leader. It sets no tool, file or model limit. The TUI writes the role name. The Companion draws a Lucide icon for each role.",
307
+ "oneOf": [
308
+ {
309
+ "const": "research",
310
+ "title": "Finds facts",
311
+ "description": "Finds facts. Reads code, docs, logs and history, and answers one question with evidence. Use it before you decide or plan."
312
+ },
313
+ {
314
+ "const": "implement",
315
+ "title": "Changes files",
316
+ "description": "Changes files. Writes code, tests, docs or configuration and runs the checks for its change. Use it for one bounded change."
317
+ },
318
+ {
319
+ "const": "verify",
320
+ "title": "Proves it works",
321
+ "description": "Proves that something works. Runs tests, reproduces a bug or checks the app, and reports pass or fail with evidence."
322
+ },
323
+ {
324
+ "const": "audit",
325
+ "title": "Judges the work",
326
+ "description": "Judges finished work. Reviews a change, plan or release for risks and mistakes, and reports findings. Give it the work, not your conclusion."
327
+ }
328
+ ]
329
+ },
273
330
  "model_pair": {
274
331
  "type": "object",
275
332
  "properties": {
@@ -338,6 +395,9 @@
338
395
  "type": "string",
339
396
  "minLength": 1
340
397
  },
398
+ "role": {
399
+ "$ref": "#/$defs/role"
400
+ },
341
401
  "status": {
342
402
  "enum": [
343
403
  "queued",
@@ -377,6 +437,42 @@
377
437
  "type": "integer",
378
438
  "minimum": 0
379
439
  },
440
+ "question": {
441
+ "type": "string",
442
+ "minLength": 1
443
+ },
444
+ "question_entry_id": {
445
+ "type": "integer",
446
+ "minimum": 1
447
+ },
448
+ "budget_request": {
449
+ "type": "object",
450
+ "properties": {
451
+ "iterations": {
452
+ "type": "integer",
453
+ "minimum": 1
454
+ },
455
+ "reason": {
456
+ "type": "string"
457
+ }
458
+ }
459
+ },
460
+ "files_request": {
461
+ "type": "object",
462
+ "properties": {
463
+ "files": {
464
+ "$ref": "#/$defs/files"
465
+ },
466
+ "reason": {
467
+ "type": "string"
468
+ }
469
+ }
470
+ },
471
+ "activity": {
472
+ "$comment": "The latest Activity line of a queued or running agent, such as Patched ~/src/a.clj.",
473
+ "type": "string",
474
+ "minLength": 1
475
+ },
380
476
  "usage": {
381
477
  "type": [
382
478
  "object",
@@ -694,6 +694,32 @@
694
694
  },
695
695
  "additionalProperties": false
696
696
  },
697
+ "toolList": {
698
+ "type": "array",
699
+ "maxItems": 256,
700
+ "uniqueItems": true,
701
+ "items": {
702
+ "type": "string",
703
+ "pattern": "^[A-Za-z_*][A-Za-z0-9_.*]*$",
704
+ "maxLength": 200
705
+ },
706
+ "description": "Tool names as python_execution binds them, such as memo.recall. * matches any characters."
707
+ },
708
+ "tools": {
709
+ "type": "object",
710
+ "properties": {
711
+ "allow": {
712
+ "$ref": "#/$defs/toolList",
713
+ "description": "Keep only these tools of each extension that the list names. Other tools of that extension, also later ones, are off."
714
+ },
715
+ "deny": {
716
+ "$ref": "#/$defs/toolList",
717
+ "description": "Turn these tools off."
718
+ }
719
+ },
720
+ "additionalProperties": false,
721
+ "description": "Tools of optional extensions that a session can call. Every scope applies: a narrower scope can turn tools off, never on."
722
+ },
697
723
  "jail": {
698
724
  "type": "object",
699
725
  "properties": {
@@ -1328,6 +1354,9 @@
1328
1354
  "jail": {
1329
1355
  "$ref": "#/$defs/jail"
1330
1356
  },
1357
+ "tools": {
1358
+ "$ref": "#/$defs/tools"
1359
+ },
1331
1360
  "environment": {
1332
1361
  "$ref": "#/$defs/environment"
1333
1362
  },
@@ -580,7 +580,7 @@
580
580
  "additionalProperties": false
581
581
  },
582
582
  "agreement": {
583
- "description": "The agreement of automatic results with human labels, with Cohen kappa and advice.",
583
+ "description": "The agreement of automatic results with human labels, with Cohen kappa, Krippendorff alpha and advice.",
584
584
  "type": "object",
585
585
  "properties": {
586
586
  "labelled": {
@@ -598,6 +598,12 @@
598
598
  "null"
599
599
  ]
600
600
  },
601
+ "alpha": {
602
+ "type": [
603
+ "number",
604
+ "null"
605
+ ]
606
+ },
601
607
  "disagreements": {
602
608
  "type": "array",
603
609
  "items": {
@@ -612,6 +618,7 @@
612
618
  "labelled",
613
619
  "agreement_percent",
614
620
  "kappa",
621
+ "alpha",
615
622
  "disagreements",
616
623
  "advice"
617
624
  ],
@@ -736,6 +736,17 @@
736
736
  },
737
737
  "path": "/v1/sessions/:sid/agents"
738
738
  },
739
+ {
740
+ "audience": "sdk",
741
+ "operations": {
742
+ "post": {
743
+ "request": "json",
744
+ "response": "json",
745
+ "extension": "background"
746
+ }
747
+ },
748
+ "path": "/v1/sessions/:sid/agents/answer"
749
+ },
739
750
  {
740
751
  "audience": "sdk",
741
752
  "operations": {
@@ -3000,14 +3011,27 @@
3000
3011
  "switch",
3001
3012
  "select",
3002
3013
  "text",
3014
+ "secret",
3003
3015
  "multiline",
3004
3016
  "number",
3005
3017
  "paths",
3006
3018
  "filesystem",
3007
3019
  "network",
3008
- "list"
3020
+ "list",
3021
+ "tools"
3009
3022
  ]
3010
3023
  },
3024
+ "is_set": {
3025
+ "type": "boolean",
3026
+ "description": "Whether a secret row has a saved value. A secret row never carries the value itself."
3027
+ },
3028
+ "suggestions": {
3029
+ "type": "array",
3030
+ "description": "Values that an editor offers as completions. Other values can still be valid.",
3031
+ "items": {
3032
+ "type": "string"
3033
+ }
3034
+ },
3011
3035
  "schema": {
3012
3036
  "type": "string"
3013
3037
  },
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://contract.blockether.com/vis/schema/toggle.json",
4
4
  "title": "Feature-toggle contract",
5
- "description": "Feature-toggle contributions and the boolean tokens accepted by settings.",
5
+ "description": "Feature-toggle contributions, and the boolean tokens and string values that settings accept.",
6
6
  "$defs": {
7
7
  "boolean_true": {
8
8
  "type": "string",
@@ -32,6 +32,12 @@
32
32
  }
33
33
  ]
34
34
  },
35
+ "string_value": {
36
+ "type": "string",
37
+ "maxLength": 4096,
38
+ "pattern": "^[^\\u0000-\\u001f\\u007f]*$",
39
+ "description": "The value of a string setting: one line without control characters."
40
+ },
35
41
  "contribution": {
36
42
  "type": "object",
37
43
  "additionalProperties": true,
@@ -83,10 +89,15 @@
83
89
  "type": {
84
90
  "enum": [
85
91
  "boolean",
86
- "enum"
92
+ "enum",
93
+ "string"
87
94
  ],
88
95
  "default": "boolean"
89
96
  },
97
+ "is_secret": {
98
+ "type": "boolean",
99
+ "description": "Makes a string setting write-only. Settings show only whether it is set, never its value."
100
+ },
90
101
  "choices": {
91
102
  "type": "array",
92
103
  "items": {},
@@ -169,6 +180,60 @@
169
180
  }
170
181
  ]
171
182
  }
183
+ },
184
+ {
185
+ "if": {
186
+ "properties": {
187
+ "type": {
188
+ "const": "string"
189
+ }
190
+ },
191
+ "required": [
192
+ "type"
193
+ ]
194
+ },
195
+ "then": {
196
+ "properties": {
197
+ "default": {
198
+ "$ref": "#/$defs/string_value"
199
+ }
200
+ },
201
+ "not": {
202
+ "required": [
203
+ "choices"
204
+ ]
205
+ }
206
+ }
207
+ },
208
+ {
209
+ "if": {
210
+ "properties": {
211
+ "is_secret": {
212
+ "const": true
213
+ }
214
+ },
215
+ "required": [
216
+ "is_secret"
217
+ ]
218
+ },
219
+ "then": {
220
+ "properties": {
221
+ "type": {
222
+ "const": "string"
223
+ },
224
+ "default": {
225
+ "const": ""
226
+ },
227
+ "scopes": {
228
+ "const": [
229
+ "global"
230
+ ]
231
+ }
232
+ },
233
+ "required": [
234
+ "type"
235
+ ]
236
+ }
172
237
  }
173
238
  ]
174
239
  },
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
8
 
9
9
  [project]
10
10
  name = "vis-agent"
11
- version = "0.3.3.dev7975"
11
+ version = "0.3.4.dev8033"
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"
@@ -0,0 +1 @@
1
+ beta-8906d28bc9e78c61bfe556c52e15d3045f046731
@@ -4,7 +4,7 @@ For installation, workflows and lifecycle choices, use the
4
4
  [Python SDK guide](https://vis.blockether.com/python-sdk.html).
5
5
  """
6
6
 
7
- from ._agent import Agent, StructuredOutputError
7
+ from ._agent import Agent, StructuredOutputError, final_answer
8
8
  from ._agents import Subagent, SubagentRecord
9
9
  from ._client import (
10
10
  Event,
@@ -70,5 +70,6 @@ __all__ = [
70
70
  "Turn",
71
71
  "VisTimeout",
72
72
  "ensure_installed",
73
+ "final_answer",
73
74
  "install",
74
75
  ]
@@ -239,7 +239,13 @@ def _syntax_message(answer: str, error: json.JSONDecodeError) -> str:
239
239
  return f"not valid JSON: {error.msg} at {where}"
240
240
 
241
241
 
242
- def _final_answer(turn: dict) -> str | None:
242
+ def final_answer(turn: dict) -> str | None:
243
+ """Return the final answer text of the turn record `turn`, or None.
244
+
245
+ A turn record has no `answer` field. The answer is the Markdown of the last
246
+ `prose` block in `turn["content"]`. A turn without that block, or with only
247
+ blank text in it, gives None.
248
+ """
243
249
  content = turn.get("content")
244
250
  if not isinstance(content, list):
245
251
  return None
@@ -397,7 +403,7 @@ def _run(
397
403
  {"turn": turn, "answer": None, "errors": [_turn_problem(turn)]}
398
404
  )
399
405
  raise StructuredOutputError(f"{name} turn did not complete", attempts)
400
- answer = _final_answer(turn)
406
+ answer = final_answer(turn)
401
407
  result, problems = contract.validate(answer)
402
408
  if not problems:
403
409
  return result
@@ -18,10 +18,16 @@ class Subagent:
18
18
  status: str
19
19
  iteration_budget: int
20
20
  iterations_used: int
21
+ role: str | None = None
21
22
  provider: str | None = None
22
23
  model: str | None = None
23
24
  routing_locked: bool = False
24
25
  pending_input: bool = False
26
+ question: str | None = None
27
+ question_entry_id: int | None = None
28
+ budget_request: dict[str, Any] | None = None
29
+ files_request: dict[str, Any] | None = None
30
+ activity: str | None = None
25
31
  usage: dict[str, Any] | None = None
26
32
  files: dict[str, list[str]] | None = None
27
33
 
@@ -231,6 +231,7 @@ class Council:
231
231
  self,
232
232
  task: str,
233
233
  *,
234
+ role: str | None = None,
234
235
  provider: str | None = None,
235
236
  model: str | None = None,
236
237
  iteration_budget: int | None = None,
@@ -247,12 +248,15 @@ class Council:
247
248
  it with different input is rejected. This is not an ordinary independent fork,
248
249
  and it does not grant broader permissions. ``files`` narrows file access with
249
250
  ``write``, ``read_only`` and ``deny`` rules: paths or globs, also for future files.
251
+ ``role`` is ``research``, ``implement``, ``verify`` or ``audit``: a label for people
252
+ that sets no limit.
250
253
  """
251
254
  body = {"task": task}
252
255
  body.update(
253
256
  {
254
257
  name: value
255
258
  for name, value in {
259
+ "role": role,
256
260
  "provider": provider,
257
261
  "iteration_budget": iteration_budget,
258
262
  "model": model,
@@ -291,8 +295,8 @@ class Council:
291
295
  ) -> tuple[SubagentRecord, ...]:
292
296
  """Spawn one subagent for each task, wait for all of them and return their records.
293
297
 
294
- A task is a string, or a dict with ``task`` and optional ``model``, ``provider``,
295
- ``iteration_budget`` and ``files``. The wait ends when every child answers, asks
298
+ A task is a string, or a dict with ``task`` and optional ``role``, ``model``,
299
+ ``provider``, ``iteration_budget`` and ``files``. The wait ends when every child answers, asks
296
300
  or stops, or after ``timeout_secs`` (at most 1800). A running child stays running.
297
301
  """
298
302
  body = {"tasks": tasks, "timeout_secs": timeout_secs}
@@ -316,15 +320,27 @@ class Council:
316
320
  return self._records("/cancel", {"session_id": session_id}, "cancel")[0]
317
321
 
318
322
  def resume(
319
- self, session_id: str, task: str, *, timeout_secs: int = 240
323
+ self,
324
+ session_id: str,
325
+ task: str,
326
+ *,
327
+ files: dict[str, list[str]] | None = None,
328
+ timeout_secs: int = 240,
320
329
  ) -> SubagentRecord:
321
330
  """Give a finished subagent a follow-up task in its own session, then wait for it.
322
331
 
323
332
  The parent must be active, as for ``spawn``: an idle parent gets
324
333
  ``inactive-session``. The child keeps its whole context. A child without
325
334
  iterations left needs ``extend`` first. A running child needs ``wait``.
335
+ ``files`` replaces the file grant of the child for the follow-up task.
326
336
  """
327
- body = {"session_id": session_id, "task": task, "timeout_secs": timeout_secs}
337
+ body: dict[str, Any] = {
338
+ "session_id": session_id,
339
+ "task": task,
340
+ "timeout_secs": timeout_secs,
341
+ }
342
+ if files is not None:
343
+ body["files"] = files
328
344
  return self._records("/resume", body, "resume", timeout_secs)[0]
329
345
 
330
346
  def extend(self, session_id: str, iterations: int) -> SubagentRecord:
@@ -340,11 +356,19 @@ class Council:
340
356
  body = {"session_id": session_id, "reason": reason}
341
357
  return self._records("/deny", body, "deny")[0]
342
358
 
359
+ def answer(self, session_id: str, text: str) -> SubagentRecord:
360
+ """Answer the open question of a subagent for its parent; the child continues."""
361
+ body = {"session_id": session_id, "text": text}
362
+ return self._records("/answer", body, "answer")[0]
363
+
343
364
  def grant(self, session_id: str, files: dict[str, list[str]]) -> SubagentRecord:
344
365
  """Add ``write``, ``read_only`` or ``deny`` file rules to the grant of a subagent.
345
366
 
346
- A grant gives at most your own access. The record has a ``warning`` when an
347
- active sibling can write the same files.
367
+ A grant gives at most your own access. A write rule that the child can already
368
+ write changes nothing. A write rule under a ``read_only`` or ``deny`` rule of the
369
+ child fails: use ``resume`` with ``files`` for a new scope. The record has a
370
+ ``warning`` for unchanged write rules and for an active sibling that can write
371
+ the same files.
348
372
  """
349
373
  body = {"session_id": session_id, "files": files}
350
374
  return self._records("/grant", body, "grant")[0]