roboshed 0.1.1.dev2__tar.gz → 0.1.1.dev4__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 (101) hide show
  1. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/CHANGELOG.md +51 -0
  2. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/PKG-INFO +123 -33
  3. roboshed-0.1.1.dev4/README.md +266 -0
  4. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/pyproject.toml +2 -2
  5. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/agents/librarian.py +2 -2
  6. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/agents/orchestrator.py +0 -3
  7. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/capabilities.py +26 -11
  8. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/dependency_health.py +35 -134
  9. roboshed-0.1.1.dev4/src/roboshed/deployments/robosprawl.py +75 -0
  10. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/identifiers.py +3 -0
  11. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/robosprawl.py +4 -2
  12. roboshed-0.1.1.dev4/src/roboshed/tools/__init__.py +52 -0
  13. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/apply_patch.py +8 -20
  14. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/run_file_command/command.py +13 -6
  15. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/run_file_command/resolve.py +3 -19
  16. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/utilities/formatting.py +3 -3
  17. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/compactification/__init__.py +4 -0
  18. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/compactification/compactify_messages.py +5 -21
  19. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/compactification/summarize.py +1 -1
  20. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/consolidate_memory.py +5 -24
  21. roboshed-0.1.1.dev4/src/roboshed/tools/contexts.py +170 -0
  22. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/__init__.py +3 -0
  23. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/contracts.py +25 -5
  24. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/drafts.py +10 -21
  25. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/factory.py +13 -14
  26. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/messages.py +5 -10
  27. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/runtime.py +2 -11
  28. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/guard.py +5 -14
  29. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/guard_formatting.py +2 -2
  30. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/memory_files.py +33 -8
  31. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/purge_files.py +8 -11
  32. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/runner.py +4 -11
  33. roboshed-0.1.1.dev4/src/roboshed/tools/sleep_between_runs.py +63 -0
  34. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/snapshot_conversation_example.py +1 -1
  35. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/snapshot_conversations.py +28 -47
  36. roboshed-0.1.1.dev4/src/roboshed/tools/stop_when_watched_agents_inactive.py +50 -0
  37. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/types.py +1 -1
  38. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_consolidate_memory.py +3 -3
  39. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_librarian.py +258 -25
  40. roboshed-0.1.1.dev4/tests/memory/test_memory_files.py +87 -0
  41. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_purge_files.py +2 -2
  42. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_snapshot_conversations.py +68 -7
  43. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_summarize_conversation.py +17 -2
  44. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_agent_deployment.py +3 -1
  45. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_agent_presets.py +2 -1
  46. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_build_guarded_tool_chain.py +3 -3
  47. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_capabilities.py +28 -42
  48. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_cli_command_chaining.py +0 -2
  49. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_cli_command_utils.py +1 -1
  50. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_cli_tools_prompt_examples.py +0 -4
  51. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_compactify_messages.py +5 -4
  52. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_compaction_runtime.py +23 -27
  53. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_dependency_health.py +128 -93
  54. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_deployment_graph.py +5 -2
  55. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_email_factory.py +80 -0
  56. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_generic_guards.py +5 -3
  57. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_guard.py +56 -4
  58. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_robosprawl.py +105 -105
  59. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_sandbox.py +4 -10
  60. roboshed-0.1.1.dev4/tests/test_tool_contexts.py +132 -0
  61. roboshed-0.1.1.dev2/README.md +0 -176
  62. roboshed-0.1.1.dev2/src/roboshed/deployments/robosprawl.py +0 -128
  63. roboshed-0.1.1.dev2/src/roboshed/tools/__init__.py +0 -21
  64. roboshed-0.1.1.dev2/src/roboshed/tools/sleep_between_runs.py +0 -67
  65. roboshed-0.1.1.dev2/tests/test_dependency_inspection.py +0 -123
  66. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/.gitignore +0 -0
  67. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/LICENSE +0 -0
  68. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/__init__.py +0 -0
  69. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/agents/__init__.py +0 -0
  70. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/deployments/__init__.py +0 -0
  71. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/models.py +0 -0
  72. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/py.typed +0 -0
  73. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/sandbox.py +0 -0
  74. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/__init__.py +0 -0
  75. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/cli_tools/__init__.py +0 -0
  76. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/cli_tools/prompts.py +0 -0
  77. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/email_tools/__init__.py +0 -0
  78. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/email_tools/prompts.py +0 -0
  79. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/file_editing/__init__.py +0 -0
  80. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/skills/file_editing/prompts.py +0 -0
  81. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/_snapshot_metadata.py +0 -0
  82. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/__init__.py +0 -0
  83. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/run_file_command/__init__.py +0 -0
  84. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/run_file_command/specs.py +0 -0
  85. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/utilities/__init__.py +0 -0
  86. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/utilities/cmd_spec.py +0 -0
  87. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/utilities/constants.py +0 -0
  88. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/cli_commands/utilities/path_extractors.py +0 -0
  89. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/compactification/prompts.py +0 -0
  90. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/compactification/summary_prompts.py +0 -0
  91. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/consolidate_memory_example.py +0 -0
  92. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/consolidate_memory_prompts.py +0 -0
  93. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/email/inputs.py +0 -0
  94. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/librarian_errors.py +0 -0
  95. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/snapshot_conversation_prompts.py +0 -0
  96. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/snapshot_normalize.py +0 -0
  97. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/truncation.py +0 -0
  98. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/src/roboshed/tools/utils.py +0 -0
  99. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/memory/test_memory_prompts.py +0 -0
  100. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_apply_patch.py +0 -0
  101. {roboshed-0.1.1.dev2 → roboshed-0.1.1.dev4}/tests/test_path_extractors.py +0 -0
@@ -2,6 +2,57 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.1.1.dev4 - 2026-09-20
6
+
7
+ - Migrate the Librarian and capability examples to Roboz's explicit
8
+ `mode=AgentMode.DETERMINISTIC` configuration. Breaking: remove
9
+ `interaction_mode` arguments from `orchestrator` and `robosprawl` calls;
10
+ invocation uses a bound host channel, defaulting to CLI. Registering a
11
+ `UserIO` adapter selects `Output.API` for the binding's lifetime.
12
+
13
+ - Keep the Librarian active for a final maintenance sweep after watched runs become
14
+ idle, so terminal conversation facts reach snapshots and memory before it stops.
15
+ Snapshot coverage now relies only on persisted message sequences, and maintenance
16
+ artifacts are published atomically.
17
+
18
+ ## 0.1.1.dev3 - 2026-09-13
19
+
20
+ - Migrate capability bindings to the central typed contexts. Existing capability
21
+ arguments, owner configuration, endpoint overrides, defaults, and maintenance
22
+ order are preserved. Each build creates fresh tool state and reports actual
23
+ resources without initializing model clients. The RoboSprawl recipe now uses
24
+ `LLMEndpointRoute` for the selectable orchestrator while its Librarian endpoint
25
+ remains fixed.
26
+
27
+ - Breaking: email factories now use the central `EmailContext`; attachment
28
+ resolvers bind a `Path` directly. `get_work_with_email` keeps its arguments and
29
+ requires a complete `EmailService`, which now inherits `ExternalDependency`
30
+ and implements `check()` using its read-only probe. Email dependencies are
31
+ inspectable without mailbox access and can be monitored without an agent.
32
+ Mailbox operations, permission checks, defaults, and error messages are preserved.
33
+ See the [context migration guide](../../docs/shed-tool-contexts.md#email-services-and-contexts).
34
+
35
+ - Breaking: bind built-in file and maintenance factories to concrete typed contexts
36
+ instead of `Ctx`; direct patch stages accept a `Path` or `TruncationSpec`.
37
+ Existing `get_*` helper arguments remain supported. Command and summary contexts
38
+ report their actual resources through `tool.external_dependencies()`. Compaction
39
+ counters belong to the context: rebinding/copying shares them; constructing a new
40
+ context creates fresh state. See the [tool-context migration](../../docs/shed-tool-contexts.md).
41
+
42
+ - Breaking: remove callback-based `inspect_dependencies`; inspect the configured
43
+ `DeployableAgent.external_dependencies()` instead; it constructs unstarted
44
+ agents using normal capability builders, without temporary sandbox isolation.
45
+ The health monitor accepts the resulting resources together with standalone
46
+ dependencies such as selectable models, deduplicating the combined sequence. Each resource owns its
47
+ synchronous `check() -> bool`; remove checker registrations and replace the
48
+ three category-specific probe helpers with `check_dependency(resource)` when
49
+ a sanitized observation is needed. Timeout, concurrency, metadata filtering,
50
+ and cached health-record behavior remain unchanged. See the README health guide.
51
+
52
+ - Breaking: replace the setter-based `RoboSprawl` class with `robosprawl(sandbox, ...)`.
53
+ Supply deployment choices directly and unpack the returned root/background
54
+ agents. See [the recipe guide](../../docs/agent-factories.md).
55
+
5
56
  ## 0.1.1.dev2 - 2026-09-12
6
57
 
7
58
  - Breaking: move permission, sandbox, watched-agent, and default model inputs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: roboshed
3
- Version: 0.1.1.dev2
3
+ Version: 0.1.1.dev4
4
4
  Import-Name: roboshed
5
5
  Summary: roboshed: optional building blocks for Roboz
6
6
  Project-URL: Repository, https://github.com/Tachion-Oy/roboz
@@ -11,7 +11,7 @@ Classifier: Development Status :: 2 - Pre-Alpha
11
11
  Classifier: Typing :: Typed
12
12
  Requires-Python: >=3.13
13
13
  Requires-Dist: pydantic>=2.12.4
14
- Requires-Dist: roboz<0.2.0,>=0.1.2.dev4
14
+ Requires-Dist: roboz<0.2.0,>=0.1.2.dev7
15
15
  Description-Content-Type: text/markdown
16
16
 
17
17
  # roboshed
@@ -25,7 +25,7 @@ install any model SDK, Proton, document SDK, web service, or backend framework.
25
25
 
26
26
  ```python
27
27
  from pathlib import Path
28
- from roboz import stop
28
+ from roboz.tools import stop
29
29
  from roboz.deployment import DeployableAgent, Capability
30
30
  from roboz.llm import MockLLMEndpoint
31
31
  from roboshed.capabilities import FileCommands, FileEditing
@@ -65,29 +65,30 @@ role definitions.
65
65
  Each capability declares the typed attributes it reads from its owning
66
66
  `DeployableAgent`. Runtime controls remain separate. Use `set_attributes()` to
67
67
  supply standalone permission policies and sandbox inputs before building.
68
+ Capability builders construct the central typed tool contexts; each build gets
69
+ fresh runtime state while retaining the selected endpoint objects. Build-based
70
+ resource inspection uses those tools without initializing model clients.
68
71
 
69
72
  See the [factory and migration guide](../../docs/agent-factories.md).
70
73
 
71
74
  ## RoboSprawl deployment recipe
72
75
 
73
- `roboshed.deployments.robosprawl.RoboSprawl` is the concrete lazy persistent
74
- orchestrator and Librarian recipe. Construct `RoboSprawl()` without inputs;
75
- supply the required scoped sandbox, endpoint getter, and memory endpoint with
76
- `set_sandbox()`, `set_endpoint_getter()`, and `set_memory_endpoint()`.
77
- `set_additional_capabilities()`, `set_specialists()`, `set_interaction_mode()`,
78
- and `set_event_sinks()` supply optional inputs (empty sequences and
79
- `interaction_mode=None` by default). A `None` mode inherits core's current output
80
- setting, falling back to CLI when none is bound. Argument-free `build()` returns
81
- a fresh root/background-agent tuple
82
- or reports missing required inputs. `robosprawl` is an alias for this class.
76
+ The recipe still requires migration to the concrete endpoint contract in this
77
+ branch; importing it currently fails on the removed lazy-reference API. The
78
+ standalone `orchestrator` and `librarian` constructors and their capabilities are
79
+ migrated. The description below records the recipe behavior to preserve.
80
+
81
+ `roboshed.deployments.robosprawl.robosprawl` is the concrete lazy persistent
82
+ orchestrator and Librarian recipe. Call it with an already-scoped sandbox,
83
+ `endpoint_getter`, `memory_endpoint`, `additional_capabilities`, `specialists`,
84
+ and optional `event_sinks`. It returns a fresh root and
85
+ background-agent tuple.
83
86
 
84
87
  The recipe loads project memory and supplies project locations through initial
85
88
  messages. Its root follows the selected model getter; the Librarian uses its
86
- separate memory endpoint. Configuration and building start no agents or provider
87
- clients and create no project directories. Use a fresh recipe per new run;
88
- setters snapshot the sandbox and sequence containers, while supplied endpoints
89
- and capability/child objects remain caller-owned. The application owns scope
90
- selection and runtime lifecycle. See the [migration example](../../docs/agent-factories.md#fixed-robosprawl-recipe).
89
+ separate memory endpoint. Construction starts no agents and creates no
90
+ directories before the build requires its persistence sinks. The application
91
+ owns scope selection and runtime lifecycle.
91
92
 
92
93
  ## Conversation compaction
93
94
 
@@ -108,8 +109,9 @@ Include this tool in an agent's `default_tools` and pass that agent's owning
108
109
  `system_prompt` and `skill_message` override the full continuation instructions.
109
110
  The tool preserves the contiguous bootstrap prefix and folds the remaining
110
111
  history, including previous summaries, into a new continuation message. Its
111
- status also carries the summary for event persistence. Each constructed tool
112
- owns its compaction count; constructing one per agent keeps counters independent.
112
+ status also carries the summary for event persistence. Each capability build
113
+ creates a fresh compaction context; tools copied or rebound to that context share
114
+ its count, while separate builds keep counters independent.
113
115
 
114
116
  Successful status reports describe the compacted history's current usage and
115
117
  headroom. Summaries are budgeted below the configured threshold and endpoint
@@ -132,12 +134,12 @@ memory pipeline; core provides the mechanisms they use.
132
134
 
133
135
  ## Context API migration
134
136
 
135
- Low-level tool factories now use `roboz.Ctx(**values)` directly, with service,
136
- endpoint, and executable objects supplied without wrappers. The specialized
137
- context classes have been removed. Existing tool builders retain their keyword
138
- arguments, defaults, permission checks, cancellation, and timeout behavior.
139
- See the [migration guide](https://github.com/Tachion-Oy/roboz/blob/main/docs/context-migration.md)
140
- for low-level context fields and state ownership.
137
+ Low-level tool factories use concrete context classes from `roboshed.tools`.
138
+ Their typed constructors own required fields, defaults, validation, and fresh
139
+ state. Direct resources such as endpoints may also be factory contexts. Existing
140
+ tool builders retain their keyword arguments, permission checks, cancellation,
141
+ and timeout behavior. See the
142
+ [context guide](../../docs/shed-tool-contexts.md) for the complete mapping.
141
143
 
142
144
 
143
145
  ## Deployable agent graphs
@@ -166,10 +168,12 @@ agent configuration. Each build creates fresh runtime state; applications can
166
168
  supply an agent-specific sink factory for persistence.
167
169
 
168
170
  The Librarian constructor declares its standard maintenance sequence:
169
- snapshots, consolidation, retention, then cadence. Pass its sandbox and the
170
- recursive foreground names directly to the constructor before attaching it as
171
- a background agent. The orchestrator also takes the configured sandbox and
172
- captures its permission policy when constructed.
171
+ snapshots, consolidation, retention, an idle check, then cadence. The first idle
172
+ observation schedules one complete final sweep without sleeping; the second idle
173
+ observation stops the Librarian. Pass its sandbox and the recursive foreground
174
+ names directly to the constructor before attaching it as a background agent. The
175
+ orchestrator also takes the configured sandbox and captures its permission policy
176
+ when constructed.
173
177
 
174
178
  Invoke the returned agent directly and retain the background agents for control.
175
179
  Repeated builds create fresh runtimes and bindings, but supplied endpoints,
@@ -177,9 +181,10 @@ capabilities, and sinks remain caller-owned. No execution state is retained on
177
181
  the definition. The old deployment wrapper, factories, host protocols, and
178
182
  result bundles are removed.
179
183
  Use core's `roboz.llm.ModelSelector` for lazy model selection.
180
- `roboz.dependencies` supplies exact dependency registration and binding;
181
- `roboshed.dependency_health` supplies isolated `inspect_dependencies`, probes,
182
- and monitoring without a web framework or provider SDK.
184
+ `roboz.dependencies` supplies the resource contract and ordered deduplication.
185
+ `DeployableAgent.external_dependencies()` builds an unstarted graph and inspects
186
+ its resources. `roboshed.dependency_health` monitors resource-owned checks without a
187
+ web framework or provider SDK.
183
188
  Permission policies treat configured folder names literally. Health scheduling
184
189
  retries observation failures; timed-out workers retain their concurrency slots
185
190
  until completion.
@@ -190,3 +195,88 @@ HUD file-link/markdown contract. The external RoboSprawl application may select
190
195
  it through `Capability(auto_loaded_skills=(robosprawl,))`. Concrete paths,
191
196
  endpoints, extra capabilities, and specialist definitions remain application
192
197
  choices. The `robosprawl` recipe assembles and builds a fresh agent graph.
198
+
199
+
200
+ ## Dependency health
201
+
202
+ Call `definition.external_dependencies()` on the configured `DeployableAgent`.
203
+ It constructs fresh agents without event sinks and delegates to their existing
204
+ tool dependency inspection, including foreground and background descendants and
205
+ unloaded skills. It returns a deduplicated `tuple[ExternalDependency, ...]` and
206
+ does not invoke agents or request endpoint initialization or availability checks.
207
+ Capability builders run normally, including any construction effects they own.
208
+
209
+ The former `inspect_dependencies` callback helper and its temporary sandbox are
210
+ removed. The optional definition method requires configuration sufficient for
211
+ normal construction; the monitor never calls it automatically. Agents do not need
212
+ to be running. Existing runtime agents can still be inspected directly. If inputs
213
+ are substituted for discovery, they must produce the resource declarations used
214
+ by the actual deployment.
215
+
216
+ The monitor accepts resources independently of agents. Combine agent resources
217
+ with other resources explicitly, for example:
218
+
219
+ ```python
220
+ monitor = DependencyHealthMonitor((
221
+ *definition.external_dependencies(),
222
+ *selectable_models,
223
+ transcription_endpoint,
224
+ ))
225
+ ```
226
+
227
+ Here `selectable_models` is a sequence of concrete `LLMEndpoint` objects; they need
228
+ not be attached to an agent or selected yet. The monitor keeps the first resource
229
+ for each dependency ID across the combined sequence. Resources are captured when
230
+ the monitor is constructed; create a new monitor if the resource set changes.
231
+
232
+ Pass those resources directly to `DependencyHealthMonitor(resources)`. Its
233
+ constructor creates pending records without performing checks. Explicit
234
+ `run_once()` or scheduled observation calls each resource's synchronous
235
+ `check() -> bool` in a worker thread. Checks own their service-specific behavior
236
+ and any required client initialization; the monitor supplies bounded concurrency,
237
+ timeouts, scheduling, and cached observations.
238
+
239
+ ```python
240
+ import asyncio
241
+ import sys
242
+
243
+ from roboz.dependencies import ExecutableDependency
244
+ from roboshed.dependency_health import DependencyHealthMonitor, DependencyStatus
245
+
246
+ program = ExecutableDependency(sys.executable)
247
+ monitor = DependencyHealthMonitor((program,))
248
+ assert monitor.records()[0].status is DependencyStatus.PENDING
249
+ asyncio.run(monitor.run_once())
250
+ assert monitor.records()[0].status is DependencyStatus.AVAILABLE
251
+ ```
252
+
253
+ `check_dependency(resource)` performs one synchronous check and returns a
254
+ `DependencyCheckResult`: `True` means available, `False` becomes `model_unavailable`
255
+ for models or `not_found` for other resources, and exceptions become sanitized
256
+ reason codes. Other return values produce `protocol_error`. Provider exception
257
+ payloads are not exposed through records. Record schemas and metadata filtering
258
+ are unchanged. Async checker callbacks and registration records are removed;
259
+ implement the synchronous method on the resource instead.
260
+
261
+ Replace `check_executable`, `check_openai_compatible_endpoint`, and
262
+ `check_network_service` with `check_dependency` when a sanitized health result
263
+ is needed, or use `resource.check()` for the primitive boolean/exception contract.
264
+ The old helper names have no compatibility aliases. Capability bindings and the
265
+ RoboSprawl deployment recipe now use the concrete context and endpoint contracts.
266
+
267
+ ## Concrete tool contexts
268
+
269
+ File-command, guard, editing, maintenance, and email factories now use concrete context
270
+ classes exported from `roboshed.tools`. Existing `get_run_file_command`,
271
+ `get_apply_patch`, and `get_compactify_messages_when_needed_tool` keyword arguments
272
+ are retained. Direct factory users should follow the
273
+ [context migration guide](../../docs/shed-tool-contexts.md), including the context
274
+ ownership rules for compaction counters. Command and summary resources are
275
+ reported through `tool.external_dependencies()` without running external work.
276
+
277
+
278
+ Email contexts live in the same module. `get_work_with_email` keeps its existing
279
+ arguments; direct email execution uses `EmailContext`, and attachment resolvers
280
+ accept `Path`. `EmailService` defines every provider operation and the resource
281
+ identity/metadata contract. Its availability check calls the existing read-only
282
+ probe. See the [email context contract](../../docs/shed-tool-contexts.md#email-services-and-contexts).
@@ -0,0 +1,266 @@
1
+ # roboshed
2
+
3
+ Reusable agent factories, capabilities, sandbox policies, tools, and skills built on Roboz. Version `0.1.1.dev1`
4
+ is a development snapshot; APIs are unstable. Dependencies are Roboz and Pydantic only.
5
+
6
+ Includes guarded Unix file commands, Python patch editing, CLI/file/email
7
+ instructions, and provider-neutral email contracts and tools. It does not
8
+ install any model SDK, Proton, document SDK, web service, or backend framework.
9
+
10
+ ```python
11
+ from pathlib import Path
12
+ from roboz.tools import stop
13
+ from roboz.deployment import DeployableAgent, Capability
14
+ from roboz.llm import MockLLMEndpoint
15
+ from roboshed.capabilities import FileCommands, FileEditing
16
+ from roboshed.sandbox import PermissionPolicy, Sandbox
17
+
18
+ permissions = PermissionPolicy.local(Path("./sandbox"))
19
+ agent = DeployableAgent(
20
+ name="file_worker",
21
+ system_prompt="Complete the user's task, then call stop.",
22
+ default_capabilities=(
23
+ Capability(tools=(stop,)),
24
+ FileCommands(),
25
+ FileEditing(),
26
+ ),
27
+ )
28
+ agent.set_agent_endpoint(MockLLMEndpoint([
29
+ {"action": "stop", "rationale": "done", "value": "Ready."}
30
+ ]))
31
+ agent.set_attributes(permissions=permissions)
32
+ agent, background_agents = agent.build()
33
+ result, messages = agent.invoke()
34
+ ```
35
+
36
+ `roboshed.capabilities` provides `FileCommands`, `FileEditing`, `Compactification`,
37
+ `ConversationSnapshots`, `MemoryConsolidation`, `ArtifactRetention`, and
38
+ `MaintenanceCadence`, alongside the `tools` and `skills` modules. Applications
39
+ choose fixed capabilities through `default_capabilities` and append application
40
+ extensions with `add_capabilities()`.
41
+ A capability owns its tools and skills. Generic `DeployableAgent` definitions
42
+ live in `roboz.deployment`.
43
+ Reusable `orchestrator` and `librarian` constructors live in `roboshed.agents`.
44
+ The orchestrator owns stop and guarded file work, and the Librarian owns
45
+ snapshots, consolidation, retention, and cadence. Root-only application
46
+ capabilities append after the agent's protected defaults, without unpacking the
47
+ role definitions.
48
+
49
+ Each capability declares the typed attributes it reads from its owning
50
+ `DeployableAgent`. Runtime controls remain separate. Use `set_attributes()` to
51
+ supply standalone permission policies and sandbox inputs before building.
52
+ Capability builders construct the central typed tool contexts; each build gets
53
+ fresh runtime state while retaining the selected endpoint objects. Build-based
54
+ resource inspection uses those tools without initializing model clients.
55
+
56
+ See the [factory and migration guide](../../docs/agent-factories.md).
57
+
58
+ ## RoboSprawl deployment recipe
59
+
60
+ The recipe still requires migration to the concrete endpoint contract in this
61
+ branch; importing it currently fails on the removed lazy-reference API. The
62
+ standalone `orchestrator` and `librarian` constructors and their capabilities are
63
+ migrated. The description below records the recipe behavior to preserve.
64
+
65
+ `roboshed.deployments.robosprawl.robosprawl` is the concrete lazy persistent
66
+ orchestrator and Librarian recipe. Call it with an already-scoped sandbox,
67
+ `endpoint_getter`, `memory_endpoint`, `additional_capabilities`, `specialists`,
68
+ and optional `event_sinks`. It returns a fresh root and
69
+ background-agent tuple.
70
+
71
+ The recipe loads project memory and supplies project locations through initial
72
+ messages. Its root follows the selected model getter; the Librarian uses its
73
+ separate memory endpoint. Construction starts no agents and creates no
74
+ directories before the build requires its persistence sinks. The application
75
+ owns scope selection and runtime lifecycle.
76
+
77
+ ## Conversation compaction
78
+
79
+ The following fragment belongs inside an agent or tool builder. `endpoint` is
80
+ the selected compaction model, and `agent_pipe` is the owning agent's event
81
+ pipe. These are independent inputs to the tool.
82
+
83
+ ```python
84
+ from roboshed.tools import get_compactify_messages_when_needed_tool
85
+
86
+ compact = get_compactify_messages_when_needed_tool(
87
+ endpoint=endpoint, threshold_percent=60, pipe=agent_pipe, timeout_s=60,
88
+ )
89
+ ```
90
+
91
+ Include this tool in an agent's `default_tools` and pass that agent's owning
92
+ `EventPipe`. The standalone factory defaults to an 80% threshold and no timeout;
93
+ `system_prompt` and `skill_message` override the full continuation instructions.
94
+ The tool preserves the contiguous bootstrap prefix and folds the remaining
95
+ history, including previous summaries, into a new continuation message. Its
96
+ status also carries the summary for event persistence. Each capability build
97
+ creates a fresh compaction context; tools copied or rebound to that context share
98
+ its count, while separate builds keep counters independent.
99
+
100
+ Successful status reports describe the compacted history's current usage and
101
+ headroom. Summaries are budgeted below the configured threshold and endpoint
102
+ capacity, including the preserved prefix and continuation payload. If there is
103
+ no room for a summary, or the returned replacement still exceeds the budget
104
+ after summarization retries, the tool returns `blocked` without changing history
105
+ or the counter. The continuation payload retains `percent_used_before`.
106
+
107
+ Cancellation and interruption propagate through the existing Roboz summarizer.
108
+ An optional positive, finite `timeout_s` bounds each provider attempt, not the
109
+ whole compaction. Failed attempts leave history and the counter unchanged;
110
+ late provider results are ignored without forcibly killing worker threads.
111
+ Summarization messages and model-call events use the supplied pipe.
112
+
113
+ The public tool name and persisted caller are `compactify_messages_when_needed`.
114
+ This tool owns the shared continuation prompts and retains RoboSprawl's caller
115
+ name. The old `robosprawl.compaction` import is
116
+ replaced by `roboshed.tools`. Shed also owns the shared summarizer and Librarian
117
+ memory pipeline; core provides the mechanisms they use.
118
+
119
+ ## Context API migration
120
+
121
+ Low-level tool factories use concrete context classes from `roboshed.tools`.
122
+ Their typed constructors own required fields, defaults, validation, and fresh
123
+ state. Direct resources such as endpoints may also be factory contexts. Existing
124
+ tool builders retain their keyword arguments, permission checks, cancellation,
125
+ and timeout behavior. See the
126
+ [context guide](../../docs/shed-tool-contexts.md) for the complete mapping.
127
+
128
+
129
+ ## Deployable agent graphs
130
+
131
+ The root `DeployableAgent` owns recursive `subagents` and `background_agents`;
132
+ both slots contain the same definition type. Configure each object explicitly
133
+ before building:
134
+
135
+ ```python
136
+ sandbox.configure_scope(folder)
137
+ definition.set_attributes(permissions=sandbox.permissions())
138
+ agent, background_agents = definition.build(event_sinks=(dispatch,))
139
+ ```
140
+
141
+ Construct each application sandbox directly:
142
+
143
+ ```python
144
+ sandbox = Sandbox(root=application_root, shared="workspace")
145
+ sandbox.configure_scope(folder)
146
+ ```
147
+
148
+ The host supplies `folder` at runtime. For now it is a direct child of the
149
+ sandbox's existing `projects_dir`, with unchanged tiered permission behavior.
150
+ Default persistence paths follow that scope. Startup memory and endpoints are
151
+ agent configuration. Each build creates fresh runtime state; applications can
152
+ supply an agent-specific sink factory for persistence.
153
+
154
+ The Librarian constructor declares its standard maintenance sequence:
155
+ snapshots, consolidation, retention, an idle check, then cadence. The first idle
156
+ observation schedules one complete final sweep without sleeping; the second idle
157
+ observation stops the Librarian. Pass its sandbox and the recursive foreground
158
+ names directly to the constructor before attaching it as a background agent. The
159
+ orchestrator also takes the configured sandbox and captures its permission policy
160
+ when constructed.
161
+
162
+ Invoke the returned agent directly and retain the background agents for control.
163
+ Repeated builds create fresh runtimes and bindings, but supplied endpoints,
164
+ capabilities, and sinks remain caller-owned. No execution state is retained on
165
+ the definition. The old deployment wrapper, factories, host protocols, and
166
+ result bundles are removed.
167
+ Use core's `roboz.llm.ModelSelector` for lazy model selection.
168
+ `roboz.dependencies` supplies the resource contract and ordered deduplication.
169
+ `DeployableAgent.external_dependencies()` builds an unstarted graph and inspects
170
+ its resources. `roboshed.dependency_health` monitors resource-owned checks without a
171
+ web framework or provider SDK.
172
+ Permission policies treat configured folder names literally. Health scheduling
173
+ retries observation failures; timed-out workers retain their concurrency slots
174
+ until completion.
175
+ See [agent factories](../../docs/agent-factories.md) for the contracts and examples.
176
+
177
+ The `robosprawl` skill from `roboshed.skills` covers sandbox orientation and the
178
+ HUD file-link/markdown contract. The external RoboSprawl application may select
179
+ it through `Capability(auto_loaded_skills=(robosprawl,))`. Concrete paths,
180
+ endpoints, extra capabilities, and specialist definitions remain application
181
+ choices. The `robosprawl` recipe assembles and builds a fresh agent graph.
182
+
183
+
184
+ ## Dependency health
185
+
186
+ Call `definition.external_dependencies()` on the configured `DeployableAgent`.
187
+ It constructs fresh agents without event sinks and delegates to their existing
188
+ tool dependency inspection, including foreground and background descendants and
189
+ unloaded skills. It returns a deduplicated `tuple[ExternalDependency, ...]` and
190
+ does not invoke agents or request endpoint initialization or availability checks.
191
+ Capability builders run normally, including any construction effects they own.
192
+
193
+ The former `inspect_dependencies` callback helper and its temporary sandbox are
194
+ removed. The optional definition method requires configuration sufficient for
195
+ normal construction; the monitor never calls it automatically. Agents do not need
196
+ to be running. Existing runtime agents can still be inspected directly. If inputs
197
+ are substituted for discovery, they must produce the resource declarations used
198
+ by the actual deployment.
199
+
200
+ The monitor accepts resources independently of agents. Combine agent resources
201
+ with other resources explicitly, for example:
202
+
203
+ ```python
204
+ monitor = DependencyHealthMonitor((
205
+ *definition.external_dependencies(),
206
+ *selectable_models,
207
+ transcription_endpoint,
208
+ ))
209
+ ```
210
+
211
+ Here `selectable_models` is a sequence of concrete `LLMEndpoint` objects; they need
212
+ not be attached to an agent or selected yet. The monitor keeps the first resource
213
+ for each dependency ID across the combined sequence. Resources are captured when
214
+ the monitor is constructed; create a new monitor if the resource set changes.
215
+
216
+ Pass those resources directly to `DependencyHealthMonitor(resources)`. Its
217
+ constructor creates pending records without performing checks. Explicit
218
+ `run_once()` or scheduled observation calls each resource's synchronous
219
+ `check() -> bool` in a worker thread. Checks own their service-specific behavior
220
+ and any required client initialization; the monitor supplies bounded concurrency,
221
+ timeouts, scheduling, and cached observations.
222
+
223
+ ```python
224
+ import asyncio
225
+ import sys
226
+
227
+ from roboz.dependencies import ExecutableDependency
228
+ from roboshed.dependency_health import DependencyHealthMonitor, DependencyStatus
229
+
230
+ program = ExecutableDependency(sys.executable)
231
+ monitor = DependencyHealthMonitor((program,))
232
+ assert monitor.records()[0].status is DependencyStatus.PENDING
233
+ asyncio.run(monitor.run_once())
234
+ assert monitor.records()[0].status is DependencyStatus.AVAILABLE
235
+ ```
236
+
237
+ `check_dependency(resource)` performs one synchronous check and returns a
238
+ `DependencyCheckResult`: `True` means available, `False` becomes `model_unavailable`
239
+ for models or `not_found` for other resources, and exceptions become sanitized
240
+ reason codes. Other return values produce `protocol_error`. Provider exception
241
+ payloads are not exposed through records. Record schemas and metadata filtering
242
+ are unchanged. Async checker callbacks and registration records are removed;
243
+ implement the synchronous method on the resource instead.
244
+
245
+ Replace `check_executable`, `check_openai_compatible_endpoint`, and
246
+ `check_network_service` with `check_dependency` when a sanitized health result
247
+ is needed, or use `resource.check()` for the primitive boolean/exception contract.
248
+ The old helper names have no compatibility aliases. Capability bindings and the
249
+ RoboSprawl deployment recipe now use the concrete context and endpoint contracts.
250
+
251
+ ## Concrete tool contexts
252
+
253
+ File-command, guard, editing, maintenance, and email factories now use concrete context
254
+ classes exported from `roboshed.tools`. Existing `get_run_file_command`,
255
+ `get_apply_patch`, and `get_compactify_messages_when_needed_tool` keyword arguments
256
+ are retained. Direct factory users should follow the
257
+ [context migration guide](../../docs/shed-tool-contexts.md), including the context
258
+ ownership rules for compaction counters. Command and summary resources are
259
+ reported through `tool.external_dependencies()` without running external work.
260
+
261
+
262
+ Email contexts live in the same module. `get_work_with_email` keeps its existing
263
+ arguments; direct email execution uses `EmailContext`, and attachment resolvers
264
+ accept `Path`. `EmailService` defines every provider operation and the resource
265
+ identity/metadata contract. Its availability check calls the existing read-only
266
+ probe. See the [email context contract](../../docs/shed-tool-contexts.md#email-services-and-contexts).
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "roboshed"
3
- version = "0.1.1.dev2"
3
+ version = "0.1.1.dev4"
4
4
  description = "roboshed: optional building blocks for Roboz"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -9,7 +9,7 @@ license = "Apache-2.0"
9
9
  license-files = ["LICENSE"]
10
10
  import-names = ["roboshed"]
11
11
  classifiers = ["Development Status :: 2 - Pre-Alpha", "Typing :: Typed"]
12
- dependencies = ["roboz>=0.1.2.dev4,<0.2.0","pydantic>=2.12.4"]
12
+ dependencies = ["roboz>=0.1.2.dev7,<0.2.0","pydantic>=2.12.4"]
13
13
 
14
14
  [build-system]
15
15
  requires = ["hatchling>=1.32"]
@@ -13,6 +13,7 @@ from roboshed.identifiers import LIBRARIAN_AGENT_NAME
13
13
  from roboshed.sandbox import Sandbox
14
14
  from roboz.deployment import DeployableAgent
15
15
  from roboz.llm import EndpointLike
16
+ from roboz.models import AgentMode
16
17
 
17
18
  LIBRARIAN_AGENT_DESCRIPTION: Final[str] = (
18
19
  "Runs deterministic maintenance cycles using the configured capabilities."
@@ -29,7 +30,7 @@ def librarian(
29
30
  agent = DeployableAgent(
30
31
  name=LIBRARIAN_AGENT_NAME,
31
32
  description=LIBRARIAN_AGENT_DESCRIPTION,
32
- is_agentic=False,
33
+ mode=AgentMode.DETERMINISTIC,
33
34
  automatic_tool_prompt=False,
34
35
  default_capabilities=(
35
36
  ConversationSnapshots(),
@@ -39,7 +40,6 @@ def librarian(
39
40
  ),
40
41
  )
41
42
  agent.set_agent_endpoint(agent_endpoint)
42
- agent.set_interaction_mode(None)
43
43
  agent.set_attributes(
44
44
  sandbox=sandbox,
45
45
  watched_agent_names=frozenset(watched_agent_names),
@@ -7,7 +7,6 @@ from roboshed.capabilities import FileCommands, FileEditing
7
7
  from roboshed.sandbox import Sandbox
8
8
  from roboz.deployment import Capability, DeployableAgent
9
9
  from roboz.llm import EndpointLike
10
- from roboz.runtime import Output
11
10
  from roboz.tools import stop
12
11
 
13
12
  ORCHESTRATOR_PROMPT = """You are the user's persistent collaborator. Help them reach their
@@ -26,7 +25,6 @@ def orchestrator(
26
25
  agent_endpoint: EndpointLike,
27
26
  subagents: Sequence[DeployableAgent] = (),
28
27
  background_agents: Sequence[DeployableAgent] = (),
29
- interaction_mode: Output | None = Output.CLI,
30
28
  initial_messages: Sequence[Path | str] = (),
31
29
  ) -> DeployableAgent:
32
30
  """Configure the orchestrator for an already-configured sandbox."""
@@ -43,7 +41,6 @@ def orchestrator(
43
41
  background_agents=tuple(background_agents),
44
42
  )
45
43
  agent.set_agent_endpoint(agent_endpoint)
46
- agent.set_interaction_mode(interaction_mode)
47
44
  agent.set_initial_messages(initial_messages)
48
45
  agent.set_attributes(permissions=sandbox.permissions())
49
46
  return agent