roboz 0.1.2.dev3__tar.gz → 0.1.2.dev5__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.
- roboz-0.1.2.dev5/CHANGELOG.md +166 -0
- roboz-0.1.2.dev5/PKG-INFO +259 -0
- roboz-0.1.2.dev5/README.md +230 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/pyproject.toml +1 -1
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/__init__.py +12 -32
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/__init__.py +6 -1
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/background_agent.py +23 -13
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/core.py +15 -13
- roboz-0.1.2.dev5/src/roboz/agent/prompt_agent_tool.py +57 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/subagent.py +5 -9
- roboz-0.1.2.dev5/src/roboz/dependencies.py +122 -0
- roboz-0.1.2.dev5/src/roboz/deployment.py +406 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/__init__.py +3 -1
- roboz-0.1.2.dev5/src/roboz/llm/binding.py +86 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/calls.py +23 -17
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/endpoints.py +173 -25
- roboz-0.1.2.dev5/src/roboz/llm/openai_compatible.py +144 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/openrouter.py +6 -21
- roboz-0.1.2.dev5/src/roboz/tooling/__init__.py +6 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tooling/_protocols.py +11 -4
- roboz-0.1.2.dev5/src/roboz/tooling/context.py +39 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tooling/core.py +44 -29
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tooling/decorators.py +13 -6
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tools/interaction.py +7 -15
- roboz-0.1.2.dev3/CHANGELOG.md +0 -84
- roboz-0.1.2.dev3/PKG-INFO +0 -217
- roboz-0.1.2.dev3/README.md +0 -188
- roboz-0.1.2.dev3/src/roboz/agent/prompt_agent_tool.py +0 -37
- roboz-0.1.2.dev3/src/roboz/dependencies.py +0 -297
- roboz-0.1.2.dev3/src/roboz/deployment.py +0 -193
- roboz-0.1.2.dev3/src/roboz/llm/binding.py +0 -150
- roboz-0.1.2.dev3/src/roboz/tooling/__init__.py +0 -6
- roboz-0.1.2.dev3/src/roboz/tooling/context.py +0 -101
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/.gitignore +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/LICENSE +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/_naming.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/_execution_context.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/_identifiers.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/_notifications.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/_prompts.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/agent/_tool_observer.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/exceptions.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/_diagnostics.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/_retry.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/_truncation.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/completion.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/llm/prompts.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/__init__.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/_schema.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/_serialization.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/_telemetry.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/core.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/models/truncation.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/py.typed +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/__init__.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/_environment.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/_external.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/_logging.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/_paths.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/events.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/io.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/observability.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/persistence/__init__.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/persistence/activity.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/persistence/schema.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/pipe.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/runtime/sinks.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/skill/__init__.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/skill/_prompts.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/skill/core.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tooling/_prompts.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tooling/_typing.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tools/__init__.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tools/_identifiers.py +0 -0
- {roboz-0.1.2.dev3 → roboz-0.1.2.dev5}/src/roboz/tools/control.py +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.1.2.dev5 - 2026-09-13
|
|
6
|
+
|
|
7
|
+
- Add `LLMEndpointRoute`, a typed live-selection layer above concrete chat
|
|
8
|
+
endpoints. Routes retain a caller-owned endpoint getter, report the current
|
|
9
|
+
selected resource without initializing clients, and resolve once per model
|
|
10
|
+
operation so in-flight calls retain their endpoint. Request and OpenRouter
|
|
11
|
+
policies support routes while keeping fixed endpoint use unchanged.
|
|
12
|
+
|
|
13
|
+
- Inspect a configured deployment with `DeployableAgent.external_dependencies()`.
|
|
14
|
+
It builds fresh, unstarted agents without event sinks and delegates to their
|
|
15
|
+
existing tool inspection, including child agents and skill resources. Capability
|
|
16
|
+
construction still runs normally; no additional dependency declaration is required.
|
|
17
|
+
|
|
18
|
+
- Initialize factory contexts lazily on invocation through the optional
|
|
19
|
+
`Materializable.materialize() -> Self` protocol. Binding, copying, and inspection
|
|
20
|
+
stay side-effect free. Endpoints support explicit early `materialize()` calls
|
|
21
|
+
while preserving their identity; prompt contexts delegate initialization.
|
|
22
|
+
Breaking: OpenAI-compatible client protocols now require `close() -> None` for
|
|
23
|
+
typed cleanup. See [the lifecycle contract](docs/dependency-primitives.md).
|
|
24
|
+
|
|
25
|
+
- Make resource-inspection declarations explicit: aggregate contexts and agents
|
|
26
|
+
implement the `HasExternalDependencies` protocol, renamed from `Context` with
|
|
27
|
+
no compatibility alias. Authors can inherit it to require
|
|
28
|
+
`external_dependencies()`; missing implementations fail type checking and
|
|
29
|
+
instantiation. Plain contexts remain unrestricted, and direct resources inherit
|
|
30
|
+
inspection from `ExternalDependency`.
|
|
31
|
+
|
|
32
|
+
- Breaking: migrate core interaction and agent factories to concrete contexts.
|
|
33
|
+
Bind interaction factories to strings, `run_subagent` to the child `Agent`,
|
|
34
|
+
and background/prompt factories to `BackgroundAgentContext`/`PromptAgentContext`
|
|
35
|
+
from `roboz.agent`. Background constructors own fresh state; rebinding and copies
|
|
36
|
+
share supplied state. Agent inspection uses live tool methods, and deployment
|
|
37
|
+
builders use the same bindings. Restore top-level agent, skill, and built-in
|
|
38
|
+
tool exports; removed dependency and `Ctx` APIs stay removed. See
|
|
39
|
+
[the primitive migration](docs/dependency-primitives.md).
|
|
40
|
+
|
|
41
|
+
- Breaking: core endpoints require synchronous OpenAI-compatible clients instead
|
|
42
|
+
of an untyped client. Client methods and request controls are checked statically;
|
|
43
|
+
the real `openai.OpenAI` client satisfies the protocols without a wrapper or an
|
|
44
|
+
SDK dependency in core. Replace placeholder or incompatible clients with a
|
|
45
|
+
conforming chat/transcription client. See [the client contract](docs/dependency-primitives.md).
|
|
46
|
+
|
|
47
|
+
- Breaking: external resource implementations must provide `check() -> bool` for
|
|
48
|
+
explicit availability checks. Executables check PATH; core endpoints use model
|
|
49
|
+
discovery without generating output. Results are uncached, absent resources
|
|
50
|
+
return `False`, and check errors propagate. Binding, copying, and inspection
|
|
51
|
+
never invoke checks. Plain contexts need no check method. See
|
|
52
|
+
[resource inspection and availability](docs/dependency-primitives.md).
|
|
53
|
+
|
|
54
|
+
- Accept any concretely typed factory context, including plain objects and lists.
|
|
55
|
+
Contexts without resource inspection are passed through unchanged and their
|
|
56
|
+
tools report no dependencies. Wrong context types remain static binding errors.
|
|
57
|
+
|
|
58
|
+
- Bind core chat and transcription endpoints directly as typed factory contexts,
|
|
59
|
+
retaining their identity and client for execution and inspection. Endpoint
|
|
60
|
+
request helpers and the selector now use concrete endpoints; lazy construction
|
|
61
|
+
and companion migrations remain deferred. Scripted endpoints report no external
|
|
62
|
+
resources. See [typed contexts and resource inspection](docs/dependency-primitives.md).
|
|
63
|
+
- Fix `@factory()` input inference so parenthesized factories retain the same
|
|
64
|
+
concrete input, output, and context types as bare `@factory` declarations.
|
|
65
|
+
|
|
66
|
+
- Breaking checkpoint: bind factories directly to concrete typed resources or
|
|
67
|
+
contexts with optional `external_dependencies()`, preserving the supplied object and
|
|
68
|
+
inspecting it live. Replace `Ctx` and tool dependency properties with concrete
|
|
69
|
+
contexts and `tool.external_dependencies()`. Dependency extension primitives
|
|
70
|
+
stay in `roboz.dependencies`; the top-level API now exposes only data and
|
|
71
|
+
tool/factory/context primitives. Remove legacy dependency bases, lazy/reference
|
|
72
|
+
helpers, and checker registration. Agent, built-in tool, and companion consumers
|
|
73
|
+
remain unmigrated; this checkpoint is not release-ready. See [typed contexts and resource inspection](docs/dependency-primitives.md)
|
|
74
|
+
for the contract, removed APIs, and migration boundary.
|
|
75
|
+
|
|
76
|
+
## 0.1.2.dev4 - 2026-09-12
|
|
77
|
+
|
|
78
|
+
- Breaking: make `DeployableAgent` an explicitly configured class. Constructor
|
|
79
|
+
capabilities are protected defaults; append capabilities and child agents with
|
|
80
|
+
the add methods, configure endpoints and runtime values separately, and unpack
|
|
81
|
+
`(agent, background_agents)` from `build()`. `build_graph()` is removed.
|
|
82
|
+
- Breaking: capability builders now declare concrete `required_attributes` and
|
|
83
|
+
receive `build(agent, pipe)`. Builds validate the complete graph before
|
|
84
|
+
constructing sinks, pipes, or tools and aggregate missing, `None`, and
|
|
85
|
+
incorrectly typed owner attributes.
|
|
86
|
+
|
|
87
|
+
## 0.1.2.dev3 - 2026-09-11
|
|
88
|
+
|
|
89
|
+
- Breaking: remove the redundant `roboz[shed]` installation extra. Install
|
|
90
|
+
`roboshed` directly; it installs its compatible core Roboz dependency.
|
|
91
|
+
|
|
92
|
+
- Add `DeployableAgent.build_graph()` to return the root agent and all background
|
|
93
|
+
handles for host lifecycle control. `build()` still returns the root alone.
|
|
94
|
+
|
|
95
|
+
- Breaking: replace `AgentDefinition` and `SubAgentSpec` with recursive
|
|
96
|
+
`DeployableAgent` definitions. Put child definitions directly in `subagents`
|
|
97
|
+
or `background_agents`; delegation tools use the child's name and description,
|
|
98
|
+
and background agents start through default tools. Construct generic
|
|
99
|
+
definitions directly with `DeployableAgent(...)`.
|
|
100
|
+
Sandbox-aware `Deployment` lives in `roboshed.deployments`, not core.
|
|
101
|
+
See `docs/agent-factories.md` for migration.
|
|
102
|
+
|
|
103
|
+
## 0.1.2.dev2 - 2026-09-09
|
|
104
|
+
|
|
105
|
+
- Breaking: remove the `roboz[openai]` extra. Install
|
|
106
|
+
`roboz-endpoints[openai]` directly for the endpoint catalogue and SDK adapter;
|
|
107
|
+
it installs core automatically. See `packages/endpoints/README.md` for migration.
|
|
108
|
+
|
|
109
|
+
- Breaking: move dependency primitives from `roboz.tooling.dependencies` and
|
|
110
|
+
`roboz.tooling` to `roboz.dependencies`. Update those imports; the existing
|
|
111
|
+
top-level `roboz` authoring API remains available. See `docs/context-migration.md`.
|
|
112
|
+
|
|
113
|
+
- Add `DependencyRoute` for live caller-owned selections. Materialization and discovery delegate to the current target without introducing a separate identity or caching the selection.
|
|
114
|
+
|
|
115
|
+
- Breaking: capability builders receive `build(pipe, *, default_endpoint)`.
|
|
116
|
+
Capabilities own their tool-specific endpoint choices and receive the agent
|
|
117
|
+
endpoint as a fallback, independently of runtime controls. Lazy/live
|
|
118
|
+
references retain identity and deferred resolution. See
|
|
119
|
+
`docs/agent-factories.md` for builder migration.
|
|
120
|
+
|
|
121
|
+
- Breaking: move the Librarian and its memory/summarization tools out of core into `roboshed.agents` and `roboshed.tools`. Use `librarian(sandbox, agent_names, agent_endpoint=...)` instead of `LibrarianConstructor` and its path record; see `docs/agent-factories.md`. Core retains control, interaction, and generic construction primitives.
|
|
122
|
+
|
|
123
|
+
- Add generic `AgentDefinition`, `AgentCapability`, `Capability`, and `SubAgentSpec` in `roboz.deployment`. Configure all tools and skills through capabilities, with fresh agent pipes and explicit sink configuration; definitions select no project, memory, or persistence conventions. See `docs/agent-factories.md`.
|
|
124
|
+
|
|
125
|
+
- Breaking: `roboz[shed]` now installs `roboshed` instead of `roboz-shed`. Update direct requirements to `roboshed` and imports from `roboz_shed` to `roboshed`; no compatibility package is provided.
|
|
126
|
+
|
|
127
|
+
### Added
|
|
128
|
+
|
|
129
|
+
- Select lazy model endpoints with `ModelSelector` from `roboz.llm` or
|
|
130
|
+
`roboz.llm.endpoints`, without requiring Shed or constructing clients.
|
|
131
|
+
|
|
132
|
+
- Bind exact dependency registrations with `roboz.dependencies`, independently
|
|
133
|
+
of Shed. Registration types, checker callbacks, and contract errors now live
|
|
134
|
+
alongside dependency discovery and resolution primitives.
|
|
135
|
+
|
|
136
|
+
- Add `ExternalDependencyReference` for replaceable resources. Endpoint helpers
|
|
137
|
+
preserve live selection and discovery through contexts, tools, and agents,
|
|
138
|
+
while lazy resources retain their identity validation and cached clients.
|
|
139
|
+
|
|
140
|
+
- Inspect resources before binding tools with `Ctx.external_dependencies()`.
|
|
141
|
+
Contexts implement `ExternalDependencySource`, preserving resource identity
|
|
142
|
+
and reflecting live nested contexts, agents, and catalogs without resolving
|
|
143
|
+
lazy resources. `external_dependencies` is now a reserved context field name;
|
|
144
|
+
see `docs/context-migration.md`.
|
|
145
|
+
|
|
146
|
+
### Fixed
|
|
147
|
+
|
|
148
|
+
- Refresh lifecycle endpoint metadata when invoking an agent again after a live
|
|
149
|
+
reference switches models, while retaining each lazy dependency's client cache.
|
|
150
|
+
|
|
151
|
+
### Changed
|
|
152
|
+
|
|
153
|
+
- **Breaking:** Construct tool contexts with `Ctx(**values)` and pass resources
|
|
154
|
+
directly. Remove `FactoryCtx`, specialized context classes, `ToolDependency`,
|
|
155
|
+
and endpoint binding wrappers; `Tool.dependencies` now returns resources.
|
|
156
|
+
See `docs/context-migration.md` for replacements and state ownership.
|
|
157
|
+
|
|
158
|
+
- Define and enforce Google-style source docstrings, and normalize tool
|
|
159
|
+
docstrings before including them in agent prompts.
|
|
160
|
+
|
|
161
|
+
## 0.1.1
|
|
162
|
+
|
|
163
|
+
- Preserve concrete nested model types across in-memory tool handoffs while
|
|
164
|
+
keeping field projection, excluded fields, validation, and detached inputs.
|
|
165
|
+
- Add optional companion extras and independent package release workflows.
|
|
166
|
+
- Keep the core's runtime dependency set unchanged.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: roboz
|
|
3
|
+
Version: 0.1.2.dev5
|
|
4
|
+
Import-Name: roboz
|
|
5
|
+
Summary: Typed primitives for composable agentic workflows
|
|
6
|
+
Project-URL: Homepage, https://github.com/Tachion-Oy/roboz
|
|
7
|
+
Project-URL: Repository, https://github.com/Tachion-Oy/roboz
|
|
8
|
+
Project-URL: Issues, https://github.com/Tachion-Oy/roboz/issues
|
|
9
|
+
Project-URL: Documentation, https://github.com/Tachion-Oy/roboz/tree/main/docs
|
|
10
|
+
Author: Tachion Oy
|
|
11
|
+
License-Expression: Apache-2.0
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: agents,llm,tool-calling,typing,workflows
|
|
14
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.13
|
|
23
|
+
Requires-Dist: pydantic>=2.12.4
|
|
24
|
+
Requires-Dist: python-dotenv>=1.2.1
|
|
25
|
+
Requires-Dist: rich>=14.2.0
|
|
26
|
+
Provides-Extra: proton-bridge-beta
|
|
27
|
+
Requires-Dist: roboz-proton-bridge<0.2.0,>=0.1.0b1; extra == 'proton-bridge-beta'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# RoboZ
|
|
31
|
+
|
|
32
|
+
**Chain tools. Skip calls.**
|
|
33
|
+
|
|
34
|
+
RoboZ is a framework for building llm powered agents. The core ingredient is that every tool can may be chained conditionally to a subsequent tool thus allowing easy injection of deterministic flows into agentic processes.
|
|
35
|
+
|
|
36
|
+
[](https://github.com/Tachion-Oy/roboz/actions/workflows/ci.yml)
|
|
37
|
+
[](https://www.python.org/downloads/)
|
|
38
|
+
[](LICENSE)
|
|
39
|
+
|
|
40
|
+
> [!WARNING]
|
|
41
|
+
> RoboZ is pre-release software requiring Python 3.13 or newer. APIs may change
|
|
42
|
+
> before 1.0.
|
|
43
|
+
|
|
44
|
+
## Basic idea
|
|
45
|
+
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+
### Problems in agents: Context bloat and excessive back-and-forth
|
|
49
|
+
Suppose the task we want to achieve is ask our buddy Bob out to lunch and then book a table. For the sake of argument assume that our agent has access to the following MCP servers (Note: this is an example, RoboZ has native Tool primitives):
|
|
50
|
+
|
|
51
|
+
- Ask Bob what they want
|
|
52
|
+
- Find a restaurant
|
|
53
|
+
- Book a table.
|
|
54
|
+
|
|
55
|
+
In the usual approach an agent is presented each MCP server separately in the their system prompt and it must call them one-by-one to complete the task. When the agent is completing the task, at every turn it must choose the correct tool, formulate its output accordingly and absorb the reply into its context, which already must contain the specific instructions on how to use each tool. In addition, at each turn one has to wait for the llm to reply, each reply costs tokens and each reply risks a mistake from the llm.
|
|
56
|
+
|
|
57
|
+
### Deterministic chains
|
|
58
|
+
The philosophy in RoboZ is that the workflow is deterministic an only choosing when to initiate is the agent's job. In RoboZ the agent would trigger the "ask Bob what they want" tool and all subsequent steps come by chaining: each tool is chained to other tools upstream and their output is passed down to the chained tool. Each link/edge may introduce a True/False condition, in this case for example if Bob interested in having lunch (with us). If he is not, RoboZ allows for the chain to break and returns back to the default tool, which for an agentic process is usually "ask the llm what to do next". The default mode is that chained tools are not presented to the agent, they are thus *passive* or in other words their role is strictly in forming deterministic workflows and they cannot be invoked.
|
|
59
|
+
|
|
60
|
+
### Message truncation
|
|
61
|
+
Lengthy tasks with many tool calls also add many tokens in the context that may not be relevant to the end result. In RoboZ all tools may choose to truncate their message i.e. not show it to the agent in its complete form or only show it in its entirety a few times and then remove it from the agents context entirely, for example.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## Code example
|
|
68
|
+
TBD
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import roboz as rz
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class LunchPreference(rz.Empty):
|
|
76
|
+
cuisine: str | None
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class Restaurant(rz.Empty):
|
|
80
|
+
name: str
|
|
81
|
+
seats_available: bool
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class Booking(rz.Empty):
|
|
85
|
+
confirmation: str
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@rz.tool
|
|
89
|
+
def plan_lunch_with_bob(
|
|
90
|
+
input: rz.Empty, messages: list[rz.Message]
|
|
91
|
+
) -> LunchPreference:
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@rz.tool
|
|
96
|
+
def retry_plan_lunch_with_bob(
|
|
97
|
+
input: Restaurant, messages: list[rz.Message]
|
|
98
|
+
) -> LunchPreference:
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@rz.tool(
|
|
103
|
+
chained_to=[plan_lunch_with_bob, retry_plan_lunch_with_bob],
|
|
104
|
+
chain_condition=lambda output: (
|
|
105
|
+
isinstance(output, LunchPreference)
|
|
106
|
+
and output.cuisine is not None
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
def find_restaurant(
|
|
110
|
+
input: LunchPreference, messages: list[rz.Message]
|
|
111
|
+
) -> Restaurant:
|
|
112
|
+
...
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
retry_plan_lunch_with_bob.chain(
|
|
116
|
+
chained_to=find_restaurant,
|
|
117
|
+
chain_condition=lambda output: (
|
|
118
|
+
isinstance(output, Restaurant) and not output.seats_available
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@rz.tool(
|
|
124
|
+
chained_to=find_restaurant,
|
|
125
|
+
chain_condition=lambda output: (
|
|
126
|
+
isinstance(output, Restaurant) and output.seats_available
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
def book_a_table(input: Restaurant, messages: list[rz.Message]) -> Booking:
|
|
130
|
+
...
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## factory closure, endpoint instance and seeing the entire prompt
|
|
134
|
+
TBD
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
## Try it
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
uv add roboz
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Or with pip:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
python -m pip install roboz
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The complete [quick start](examples/quickstart.py) uses a deterministic mock
|
|
150
|
+
endpoint. Bob first chooses sushi; when no seats are available, the typed chain
|
|
151
|
+
retries the planner, routes his second choice to pizza, and books—all from one
|
|
152
|
+
model-selected entry into the chain and without credentials:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
uv run python examples/quickstart.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
For an unpublished checkout, first run `uv sync --locked --dev`. PyPI commands
|
|
159
|
+
require a published release; see the [build and test guide](docs/build-and-test.md)
|
|
160
|
+
for local wheels.
|
|
161
|
+
|
|
162
|
+
## Control what reaches the model
|
|
163
|
+
|
|
164
|
+
Context is a projection, not an ever-growing transcript. Every `Message` can
|
|
165
|
+
carry a lifecycle policy: keep an output intact while it is recent, reduce it
|
|
166
|
+
to a stub later, and remove it from model context when it is stale.
|
|
167
|
+
`NO_MESSAGE` keeps operational chatter out of model context immediately. These
|
|
168
|
+
policies affect only what the model sees; runtime events and persisted messages
|
|
169
|
+
retain the full record.
|
|
170
|
+
|
|
171
|
+
The prompt is not assembled behind an opaque stack of framework layers. The
|
|
172
|
+
complete generated system prompt is available before invocation:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
print(agent.full_system_prompt)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## One execution abstraction
|
|
179
|
+
|
|
180
|
+
Roboz uses tools for work and for orchestration instead of adding a separate
|
|
181
|
+
hook mechanism for each new concern.
|
|
182
|
+
|
|
183
|
+
| Concern | Roboz abstraction |
|
|
184
|
+
| --- | --- |
|
|
185
|
+
| A model-selectable action | Active `@tool` |
|
|
186
|
+
| A deterministic follow-up | Passive chained tool |
|
|
187
|
+
| Runtime configuration or dependencies | `@factory` bound to a concrete typed object |
|
|
188
|
+
| Startup, preflight, and default flow | `default_tools` |
|
|
189
|
+
| Synchronous delegation | A subagent exposed as a named tool |
|
|
190
|
+
| Background work | An idempotent background-start tool in the default flow |
|
|
191
|
+
|
|
192
|
+
Tools remain independently testable callables with typed inputs and outputs.
|
|
193
|
+
An agent's dependency view is derived from this same tool graph rather than a
|
|
194
|
+
second registry.
|
|
195
|
+
|
|
196
|
+
## Put models where they belong
|
|
197
|
+
|
|
198
|
+
Each agent owns its endpoint. A model-backed factory can bind another endpoint
|
|
199
|
+
directly, so a planner, specialist, summarizer, or transcription tool does not
|
|
200
|
+
have to share a model merely because it belongs to the same workflow.
|
|
201
|
+
`LLMEndpointRoute` follows a typed endpoint getter when a tool or agent should
|
|
202
|
+
track live model selection; concrete endpoints keep other uses fixed.
|
|
203
|
+
|
|
204
|
+
Provider SDKs remain outside core. The `roboz` package supplies the agent,
|
|
205
|
+
tooling, model, runtime, persistence, dependency, and deployment primitives;
|
|
206
|
+
install integrations only where they are needed.
|
|
207
|
+
|
|
208
|
+
## Core primitives
|
|
209
|
+
|
|
210
|
+
| Primitive | Role |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| `rz.Agent` | Owns the active tool surface, prompt, invoke loop, and runtime events. |
|
|
213
|
+
| `@rz.tool` | Defines an action with typed input and output models. |
|
|
214
|
+
| `@rz.factory` | Binds a concrete typed context or resource to a tool. |
|
|
215
|
+
| `rz.Skill` | Packages reusable instructions and optional tools. |
|
|
216
|
+
| `rz.Message` | Carries content and its model-context lifecycle. |
|
|
217
|
+
| `roboz.deployment.DeployableAgent` | Composes capabilities, subagents, and background agents. |
|
|
218
|
+
|
|
219
|
+
## Optional ecosystem
|
|
220
|
+
|
|
221
|
+
Start with core and add only the integrations the application needs.
|
|
222
|
+
|
|
223
|
+
| Distribution | Adds |
|
|
224
|
+
| --- | --- |
|
|
225
|
+
| `roboshed` | Guarded file and CLI tools, memory, compaction, reusable agents, and deployment recipes. |
|
|
226
|
+
| `roboz-endpoints` | Lazy model catalogues and SDK adapters for OpenAI-compatible providers. |
|
|
227
|
+
| `roboz-proton-bridge` | Proton Bridge email tools. |
|
|
228
|
+
|
|
229
|
+
See the [add-on guide](docs/addons.md) for installation and composition, and the
|
|
230
|
+
[endpoint guide](packages/endpoints/README.md) for model selection and provider
|
|
231
|
+
adapters.
|
|
232
|
+
|
|
233
|
+
## Documentation
|
|
234
|
+
|
|
235
|
+
| Guide | Start here for |
|
|
236
|
+
| --- | --- |
|
|
237
|
+
| [Tool authoring](docs/tool-authoring.md) | Chaining, factories, conditions, and typed handoffs |
|
|
238
|
+
| [Agent authoring](docs/agent-authoring.md) | Agent composition and prompt policy |
|
|
239
|
+
| [Reference](docs/reference.md) | Runtime and API semantics |
|
|
240
|
+
| [Message truncation example](examples/message_truncation.py) | Sliding model-context visibility |
|
|
241
|
+
| [Testing practices](docs/testing-practices.md) | Deterministic workflow and contract tests |
|
|
242
|
+
|
|
243
|
+
## Development
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
uv sync --locked --dev
|
|
247
|
+
uv run pytest
|
|
248
|
+
uv run ruff check
|
|
249
|
+
uv run pyright
|
|
250
|
+
bash scripts/run_type_tests.sh
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) and the
|
|
254
|
+
[build and test guide](docs/build-and-test.md) for the complete release gate.
|
|
255
|
+
Roboz is typed and ships a PEP 561 `py.typed` marker.
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
Roboz is licensed under the [Apache License 2.0](LICENSE). Copyright © 2026 Tachion Oy.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# RoboZ
|
|
2
|
+
|
|
3
|
+
**Chain tools. Skip calls.**
|
|
4
|
+
|
|
5
|
+
RoboZ is a framework for building llm powered agents. The core ingredient is that every tool can may be chained conditionally to a subsequent tool thus allowing easy injection of deterministic flows into agentic processes.
|
|
6
|
+
|
|
7
|
+
[](https://github.com/Tachion-Oy/roboz/actions/workflows/ci.yml)
|
|
8
|
+
[](https://www.python.org/downloads/)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
> [!WARNING]
|
|
12
|
+
> RoboZ is pre-release software requiring Python 3.13 or newer. APIs may change
|
|
13
|
+
> before 1.0.
|
|
14
|
+
|
|
15
|
+
## Basic idea
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
### Problems in agents: Context bloat and excessive back-and-forth
|
|
20
|
+
Suppose the task we want to achieve is ask our buddy Bob out to lunch and then book a table. For the sake of argument assume that our agent has access to the following MCP servers (Note: this is an example, RoboZ has native Tool primitives):
|
|
21
|
+
|
|
22
|
+
- Ask Bob what they want
|
|
23
|
+
- Find a restaurant
|
|
24
|
+
- Book a table.
|
|
25
|
+
|
|
26
|
+
In the usual approach an agent is presented each MCP server separately in the their system prompt and it must call them one-by-one to complete the task. When the agent is completing the task, at every turn it must choose the correct tool, formulate its output accordingly and absorb the reply into its context, which already must contain the specific instructions on how to use each tool. In addition, at each turn one has to wait for the llm to reply, each reply costs tokens and each reply risks a mistake from the llm.
|
|
27
|
+
|
|
28
|
+
### Deterministic chains
|
|
29
|
+
The philosophy in RoboZ is that the workflow is deterministic an only choosing when to initiate is the agent's job. In RoboZ the agent would trigger the "ask Bob what they want" tool and all subsequent steps come by chaining: each tool is chained to other tools upstream and their output is passed down to the chained tool. Each link/edge may introduce a True/False condition, in this case for example if Bob interested in having lunch (with us). If he is not, RoboZ allows for the chain to break and returns back to the default tool, which for an agentic process is usually "ask the llm what to do next". The default mode is that chained tools are not presented to the agent, they are thus *passive* or in other words their role is strictly in forming deterministic workflows and they cannot be invoked.
|
|
30
|
+
|
|
31
|
+
### Message truncation
|
|
32
|
+
Lengthy tasks with many tool calls also add many tokens in the context that may not be relevant to the end result. In RoboZ all tools may choose to truncate their message i.e. not show it to the agent in its complete form or only show it in its entirety a few times and then remove it from the agents context entirely, for example.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Code example
|
|
39
|
+
TBD
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import roboz as rz
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class LunchPreference(rz.Empty):
|
|
47
|
+
cuisine: str | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class Restaurant(rz.Empty):
|
|
51
|
+
name: str
|
|
52
|
+
seats_available: bool
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class Booking(rz.Empty):
|
|
56
|
+
confirmation: str
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@rz.tool
|
|
60
|
+
def plan_lunch_with_bob(
|
|
61
|
+
input: rz.Empty, messages: list[rz.Message]
|
|
62
|
+
) -> LunchPreference:
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@rz.tool
|
|
67
|
+
def retry_plan_lunch_with_bob(
|
|
68
|
+
input: Restaurant, messages: list[rz.Message]
|
|
69
|
+
) -> LunchPreference:
|
|
70
|
+
...
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@rz.tool(
|
|
74
|
+
chained_to=[plan_lunch_with_bob, retry_plan_lunch_with_bob],
|
|
75
|
+
chain_condition=lambda output: (
|
|
76
|
+
isinstance(output, LunchPreference)
|
|
77
|
+
and output.cuisine is not None
|
|
78
|
+
),
|
|
79
|
+
)
|
|
80
|
+
def find_restaurant(
|
|
81
|
+
input: LunchPreference, messages: list[rz.Message]
|
|
82
|
+
) -> Restaurant:
|
|
83
|
+
...
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
retry_plan_lunch_with_bob.chain(
|
|
87
|
+
chained_to=find_restaurant,
|
|
88
|
+
chain_condition=lambda output: (
|
|
89
|
+
isinstance(output, Restaurant) and not output.seats_available
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@rz.tool(
|
|
95
|
+
chained_to=find_restaurant,
|
|
96
|
+
chain_condition=lambda output: (
|
|
97
|
+
isinstance(output, Restaurant) and output.seats_available
|
|
98
|
+
),
|
|
99
|
+
)
|
|
100
|
+
def book_a_table(input: Restaurant, messages: list[rz.Message]) -> Booking:
|
|
101
|
+
...
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## factory closure, endpoint instance and seeing the entire prompt
|
|
105
|
+
TBD
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
## Try it
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
uv add roboz
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Or with pip:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
python -m pip install roboz
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The complete [quick start](examples/quickstart.py) uses a deterministic mock
|
|
121
|
+
endpoint. Bob first chooses sushi; when no seats are available, the typed chain
|
|
122
|
+
retries the planner, routes his second choice to pizza, and books—all from one
|
|
123
|
+
model-selected entry into the chain and without credentials:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uv run python examples/quickstart.py
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For an unpublished checkout, first run `uv sync --locked --dev`. PyPI commands
|
|
130
|
+
require a published release; see the [build and test guide](docs/build-and-test.md)
|
|
131
|
+
for local wheels.
|
|
132
|
+
|
|
133
|
+
## Control what reaches the model
|
|
134
|
+
|
|
135
|
+
Context is a projection, not an ever-growing transcript. Every `Message` can
|
|
136
|
+
carry a lifecycle policy: keep an output intact while it is recent, reduce it
|
|
137
|
+
to a stub later, and remove it from model context when it is stale.
|
|
138
|
+
`NO_MESSAGE` keeps operational chatter out of model context immediately. These
|
|
139
|
+
policies affect only what the model sees; runtime events and persisted messages
|
|
140
|
+
retain the full record.
|
|
141
|
+
|
|
142
|
+
The prompt is not assembled behind an opaque stack of framework layers. The
|
|
143
|
+
complete generated system prompt is available before invocation:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
print(agent.full_system_prompt)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## One execution abstraction
|
|
150
|
+
|
|
151
|
+
Roboz uses tools for work and for orchestration instead of adding a separate
|
|
152
|
+
hook mechanism for each new concern.
|
|
153
|
+
|
|
154
|
+
| Concern | Roboz abstraction |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| A model-selectable action | Active `@tool` |
|
|
157
|
+
| A deterministic follow-up | Passive chained tool |
|
|
158
|
+
| Runtime configuration or dependencies | `@factory` bound to a concrete typed object |
|
|
159
|
+
| Startup, preflight, and default flow | `default_tools` |
|
|
160
|
+
| Synchronous delegation | A subagent exposed as a named tool |
|
|
161
|
+
| Background work | An idempotent background-start tool in the default flow |
|
|
162
|
+
|
|
163
|
+
Tools remain independently testable callables with typed inputs and outputs.
|
|
164
|
+
An agent's dependency view is derived from this same tool graph rather than a
|
|
165
|
+
second registry.
|
|
166
|
+
|
|
167
|
+
## Put models where they belong
|
|
168
|
+
|
|
169
|
+
Each agent owns its endpoint. A model-backed factory can bind another endpoint
|
|
170
|
+
directly, so a planner, specialist, summarizer, or transcription tool does not
|
|
171
|
+
have to share a model merely because it belongs to the same workflow.
|
|
172
|
+
`LLMEndpointRoute` follows a typed endpoint getter when a tool or agent should
|
|
173
|
+
track live model selection; concrete endpoints keep other uses fixed.
|
|
174
|
+
|
|
175
|
+
Provider SDKs remain outside core. The `roboz` package supplies the agent,
|
|
176
|
+
tooling, model, runtime, persistence, dependency, and deployment primitives;
|
|
177
|
+
install integrations only where they are needed.
|
|
178
|
+
|
|
179
|
+
## Core primitives
|
|
180
|
+
|
|
181
|
+
| Primitive | Role |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `rz.Agent` | Owns the active tool surface, prompt, invoke loop, and runtime events. |
|
|
184
|
+
| `@rz.tool` | Defines an action with typed input and output models. |
|
|
185
|
+
| `@rz.factory` | Binds a concrete typed context or resource to a tool. |
|
|
186
|
+
| `rz.Skill` | Packages reusable instructions and optional tools. |
|
|
187
|
+
| `rz.Message` | Carries content and its model-context lifecycle. |
|
|
188
|
+
| `roboz.deployment.DeployableAgent` | Composes capabilities, subagents, and background agents. |
|
|
189
|
+
|
|
190
|
+
## Optional ecosystem
|
|
191
|
+
|
|
192
|
+
Start with core and add only the integrations the application needs.
|
|
193
|
+
|
|
194
|
+
| Distribution | Adds |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| `roboshed` | Guarded file and CLI tools, memory, compaction, reusable agents, and deployment recipes. |
|
|
197
|
+
| `roboz-endpoints` | Lazy model catalogues and SDK adapters for OpenAI-compatible providers. |
|
|
198
|
+
| `roboz-proton-bridge` | Proton Bridge email tools. |
|
|
199
|
+
|
|
200
|
+
See the [add-on guide](docs/addons.md) for installation and composition, and the
|
|
201
|
+
[endpoint guide](packages/endpoints/README.md) for model selection and provider
|
|
202
|
+
adapters.
|
|
203
|
+
|
|
204
|
+
## Documentation
|
|
205
|
+
|
|
206
|
+
| Guide | Start here for |
|
|
207
|
+
| --- | --- |
|
|
208
|
+
| [Tool authoring](docs/tool-authoring.md) | Chaining, factories, conditions, and typed handoffs |
|
|
209
|
+
| [Agent authoring](docs/agent-authoring.md) | Agent composition and prompt policy |
|
|
210
|
+
| [Reference](docs/reference.md) | Runtime and API semantics |
|
|
211
|
+
| [Message truncation example](examples/message_truncation.py) | Sliding model-context visibility |
|
|
212
|
+
| [Testing practices](docs/testing-practices.md) | Deterministic workflow and contract tests |
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
uv sync --locked --dev
|
|
218
|
+
uv run pytest
|
|
219
|
+
uv run ruff check
|
|
220
|
+
uv run pyright
|
|
221
|
+
bash scripts/run_type_tests.sh
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) and the
|
|
225
|
+
[build and test guide](docs/build-and-test.md) for the complete release gate.
|
|
226
|
+
Roboz is typed and ships a PEP 561 `py.typed` marker.
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
Roboz is licensed under the [Apache License 2.0](LICENSE). Copyright © 2026 Tachion Oy.
|