b3-prosaic-harness 0.7.1__py3-none-any.whl
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.
- b3_prosaic_harness-0.7.1.dist-info/METADATA +389 -0
- b3_prosaic_harness-0.7.1.dist-info/RECORD +26 -0
- b3_prosaic_harness-0.7.1.dist-info/WHEEL +5 -0
- b3_prosaic_harness-0.7.1.dist-info/entry_points.txt +2 -0
- b3_prosaic_harness-0.7.1.dist-info/licenses/LICENSE +202 -0
- b3_prosaic_harness-0.7.1.dist-info/licenses/NOTICE +5 -0
- b3_prosaic_harness-0.7.1.dist-info/top_level.txt +1 -0
- prosaic_harness/__init__.py +22 -0
- prosaic_harness/admission_data.py +207 -0
- prosaic_harness/bundles.py +138 -0
- prosaic_harness/cli.py +88 -0
- prosaic_harness/contracts.py +152 -0
- prosaic_harness/discovery.py +196 -0
- prosaic_harness/engine.py +864 -0
- prosaic_harness/errors.py +107 -0
- prosaic_harness/factory.py +722 -0
- prosaic_harness/file_store.py +158 -0
- prosaic_harness/graph_admission.py +193 -0
- prosaic_harness/interaction.py +94 -0
- prosaic_harness/observations.py +44 -0
- prosaic_harness/run_store.py +138 -0
- prosaic_harness/schema_validation.py +247 -0
- prosaic_harness/store.py +105 -0
- prosaic_harness/testing.py +32 -0
- prosaic_harness/validation.py +38 -0
- prosaic_harness/workflow.py +289 -0
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: b3-prosaic-harness
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: Small durable workflows and validation around neutral Prosaic agents
|
|
5
|
+
Author: B3 Cognition
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: NOTICE
|
|
11
|
+
Requires-Dist: b3-prosaic-runtime<0.9,>=0.8
|
|
12
|
+
Requires-Dist: PyYAML>=6.0
|
|
13
|
+
Requires-Dist: jsonschema>=4.23
|
|
14
|
+
Requires-Dist: referencing>=0.28.4
|
|
15
|
+
Provides-Extra: test
|
|
16
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
17
|
+
Requires-Dist: build>=1; extra == "test"
|
|
18
|
+
Requires-Dist: setuptools>=77; extra == "test"
|
|
19
|
+
Requires-Dist: wheel; extra == "test"
|
|
20
|
+
Requires-Dist: packaging; extra == "test"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# Prosaic Harness
|
|
24
|
+
|
|
25
|
+
Version **0.7.1** is the candidate `b3-prosaic-harness` index distribution, with
|
|
26
|
+
`b3-prosaic-runtime>=0.8,<0.9` and optional `b3-prosaic-harness-postgres` **0.2.1**.
|
|
27
|
+
Imports (`prosaic_harness`) and CLI commands (`prosaic-harness`) remain unchanged.
|
|
28
|
+
The five-package release train is pending final qualification and publication;
|
|
29
|
+
see [package migration](docs/package-migration.md) for fresh-environment installs.
|
|
30
|
+
|
|
31
|
+
Version **0.6.2** added a [validated in-memory workflow factory](docs/workflow-factory.md)
|
|
32
|
+
for approved agents, native tool registries and client-generated graphs. The host
|
|
33
|
+
supplies policy and private bindings; proposals need no filesystem directory.
|
|
34
|
+
Admission, schema bounds and durable failure recovery are enforced before execution.
|
|
35
|
+
|
|
36
|
+
Optional [customer accounting context](docs/accounting.md) preserves attribution
|
|
37
|
+
through workflow retries and resume. Existing callers and saved runs remain supported;
|
|
38
|
+
durable usage recording is explicitly enabled through Prosaic Runtime.
|
|
39
|
+
|
|
40
|
+
Version **0.6.1** fixes lease-registration admission in the separately installed PostgreSQL adapter
|
|
41
|
+
(**0.1.1**) for cross-worker durable workflows. Core remains database-free; filesystem constructors/CLI remain supported.
|
|
42
|
+
See [explicit database setup/grants](adapters/postgres/README.md) and the
|
|
43
|
+
[zero-model-call two-worker example](examples/postgres/README.md). Prose tools
|
|
44
|
+
do not grant database access; applications retain tenant authorization and
|
|
45
|
+
filter private run state.
|
|
46
|
+
|
|
47
|
+
The [RunStore ruling register](docs/decisions/2026-10-08-run-store-postgres-rulings.md)
|
|
48
|
+
preserves implementation/review decisions, reasons and risks with stable IDs.
|
|
49
|
+
|
|
50
|
+
Version 0.5.0 adds schema-validated human responses at durable workflow pauses,
|
|
51
|
+
with trusted validators and retained feedback for downstream agents and checks.
|
|
52
|
+
It pins Runtime v0.5.3 and automatically installs Python Prosaic v0.3.1.
|
|
53
|
+
Installation and CI no longer require Node.js or npm.
|
|
54
|
+
|
|
55
|
+
Version 0.4.0 adds [manifest-defined CLI tools](examples/README.md#custom-command-line-tools)
|
|
56
|
+
through the normal workflow CLI, with offline availability checks and required
|
|
57
|
+
native execution evidence. Current candidates select the compatible Runtime 0.8 series.
|
|
58
|
+
|
|
59
|
+
## CLI permissions and sandboxing
|
|
60
|
+
|
|
61
|
+
Harness **0.7.1** retains CLI sandbox policy enforcement and selects Runtime
|
|
62
|
+
**0.8.x**, which provides `cli_sandbox_v1`. Follow the
|
|
63
|
+
[sandboxed workflow walkthrough](examples/README.md#sandboxed-cli-workflow-harness-042)
|
|
64
|
+
for installation, offline validation and live execution.
|
|
65
|
+
The complete blueprint is [cli-tool-sandboxed.yml](examples/cli-tool-sandboxed.yml).
|
|
66
|
+
|
|
67
|
+
Permissions are operator-owned, not granted by prose:
|
|
68
|
+
|
|
69
|
+
| Location | Setting | Meaning |
|
|
70
|
+
| --- | --- | --- |
|
|
71
|
+
| Agent Markdown | `tools: [analyze_spec]` | Request the tool; not authorization |
|
|
72
|
+
| Runtime YAML | `allowed_tools: [analyze_spec]` and reviewed `tool_directories` | Allow the tool and trust its manifest/executable |
|
|
73
|
+
| Workflow agent step | `tools: [analyze_spec]`, `read_roots: [evidence]` | Grant that step the tool and narrow readable inputs |
|
|
74
|
+
| Runtime YAML | `cli_sandbox: {mode: required}` | Enforce OS isolation for CLI execution and probes |
|
|
75
|
+
| Workflow agent step | `require_tools: [analyze_spec]` | Require observed successful execution; grants nothing extra |
|
|
76
|
+
|
|
77
|
+
All tool permission layers must agree. `validate` loads the workflow and runs
|
|
78
|
+
offline CLI preflight; it does not contact a model or need an endpoint key.
|
|
79
|
+
The sandbox is off by default. Required mode fails closed if unavailable;
|
|
80
|
+
Linux needs Bubblewrap >= 0.12.0 and permitted user namespaces, while macOS needs
|
|
81
|
+
Seatbelt's `sandbox-exec`. See [Runtime's setup](https://github.com/B3Cognition/prosaic-runtime/blob/main/docs/cli-tools.md).
|
|
82
|
+
|
|
83
|
+
Sandboxed CLIs can read granted evidence and write private scratch, but cannot
|
|
84
|
+
write the workspace or reach the host IP network. Keep host Unix sockets outside
|
|
85
|
+
granted directories. Extra dependencies need narrow `runtime_roots`, not HOME or
|
|
86
|
+
`/`. This does not sandbox Python callbacks, validators or native coding providers;
|
|
87
|
+
builtin read tools retain their existing path checks. Harness itself still writes
|
|
88
|
+
durable run state on the host. Required-mode policy is sealed into workflow
|
|
89
|
+
identity: changes invalidate existing approvals/resume, and injected adapters
|
|
90
|
+
cannot silently downgrade it. Use a fresh run directory when changing policy.
|
|
91
|
+
|
|
92
|
+
## Overview
|
|
93
|
+
|
|
94
|
+
The [custom-tool embedding example](examples/README.md#host-registered-custom-tools)
|
|
95
|
+
adds catalogue lookup, version-bound native execution evidence, deterministic
|
|
96
|
+
answer admission and a human pause. It requires Harness v0.4.0+ / Runtime v0.5.0+.
|
|
97
|
+
|
|
98
|
+
A small Python harness for durable workflows built from neutral Prosaic agents.
|
|
99
|
+
Define a graph in YAML, execute agents through Prosaic Runtime, validate their
|
|
100
|
+
JSON outputs, and resume from local checkpoints. Apache-2.0.
|
|
101
|
+
|
|
102
|
+
| Component | Owns |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| [Prosaic](https://github.com/B3Cognition/prosaic) | Markdown agents and resource inspection |
|
|
105
|
+
| [Prosaic Runtime](https://github.com/B3Cognition/prosaic-runtime) | One model invocation, model tiers, tools, streaming, permissions |
|
|
106
|
+
| Prosaic Harness | Steps, validation, transitions, review loops, human pauses, run evidence |
|
|
107
|
+
|
|
108
|
+
The initial release supports Linux and macOS with Python 3.11+. It needs an
|
|
109
|
+
existing OpenAI-compatible endpoint and the Python Prosaic CLI. Windows
|
|
110
|
+
users can use WSL. The library imports no Echelon code.
|
|
111
|
+
|
|
112
|
+
Version 0.2.0 adds versioned approvals, trusted checks and final-output validation,
|
|
113
|
+
and hash-bound read provenance. Version 0.3.0 pins Prosaic Runtime 0.4.0, adding
|
|
114
|
+
opt-in acquisition, strict initial-tool enforcement, admission-time resource
|
|
115
|
+
checks and larger incident-review examples. State format is
|
|
116
|
+
version 2; existing 0.1 runs must start afresh. See
|
|
117
|
+
[hardening setup and contracts](docs/hardening.md).
|
|
118
|
+
|
|
119
|
+
## First run
|
|
120
|
+
|
|
121
|
+
Install Git and Python 3.11+ before starting. Use an explicit Python
|
|
122
|
+
environment so another application's older runtime cannot be picked up by accident.
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
git clone https://github.com/B3Cognition/prosaic-harness.git
|
|
126
|
+
cd prosaic-harness
|
|
127
|
+
git checkout <exact-candidate-commit>
|
|
128
|
+
python3 -m venv .venv
|
|
129
|
+
.venv/bin/python -m pip install --find-links /absolute/path/to/curated-wheelhouse .
|
|
130
|
+
|
|
131
|
+
export PATH="$PWD/.venv/bin:$PATH"
|
|
132
|
+
prosaic --help
|
|
133
|
+
.venv/bin/prosaic-harness --help
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
ALWAYS use a fresh clone/environment for migration; NEVER reuse an environment
|
|
137
|
+
containing legacy distributions. In a future terminal, return to the repository and add its `.venv/bin` to PATH
|
|
138
|
+
again. Node.js and npm are not required. Candidate dependency metadata selects
|
|
139
|
+
`b3-prosaic-runtime` 0.8.x, `b3-prosaic` 0.4.x, PyYAML, jsonschema and referencing.
|
|
140
|
+
Use only the manifest-selected b3 wheels in the curated wheelhouse. Candidate
|
|
141
|
+
installation requires the Runtime 0.8 producer; it is not yet a published index install.
|
|
142
|
+
No sibling checkout or manual Prosaic installation is needed. Older Harness
|
|
143
|
+
tags retain their historical installation docs.
|
|
144
|
+
|
|
145
|
+
### Configure an endpoint
|
|
146
|
+
|
|
147
|
+
Edit `examples/runtime.yml`: replace the localhost URL and `your-model` with your
|
|
148
|
+
operator's values. Each profile names an endpoint, model, credential environment
|
|
149
|
+
variable, and optional transport features. Prose `model_tier` selects a profile
|
|
150
|
+
through `routes`. Set the key without putting it into YAML:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
export LOCAL_LLM_API_KEY="$(.venv/bin/python -c 'import getpass; print(getpass.getpass("Endpoint key: "))')"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
An unauthenticated endpoint may omit `api_key_env`. If your endpoint rejects
|
|
157
|
+
streaming usage reporting, set `stream_options: false`. Diagnostics do not
|
|
158
|
+
generate text unless you explicitly request inference:
|
|
159
|
+
|
|
160
|
+
```sh
|
|
161
|
+
.venv/bin/prosaic-runtime doctor --config examples/runtime.yml --output text
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For the private TokenProxy demo, `examples/tokenproxy.yml` supplies the four model
|
|
165
|
+
profiles. `examples/tokenproxy-single.yml` and `examples/tokenproxy-review.yml`
|
|
166
|
+
select that configuration. They require access to `10.16.81.27:8080`:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
source ~/.zshrc
|
|
170
|
+
export TOKENPROXY_KEY
|
|
171
|
+
.venv/bin/prosaic-runtime doctor --config examples/tokenproxy.yml --output text
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Run one agent with validation
|
|
175
|
+
|
|
176
|
+
```sh
|
|
177
|
+
.venv/bin/prosaic-harness validate examples/single.yml --checks examples/checks.py
|
|
178
|
+
.venv/bin/prosaic-harness run examples/single.yml \
|
|
179
|
+
--checks examples/checks.py --input examples/request.json --run-dir runs/first-note
|
|
180
|
+
.venv/bin/prosaic-harness status --run-dir runs/first-note
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
For TokenProxy, substitute `examples/tokenproxy-single.yml`. This makes a real
|
|
184
|
+
model request. The briefer must return JSON matching `examples/schemas/brief.json`;
|
|
185
|
+
invalid output triggers bounded retries with validation feedback. Completion
|
|
186
|
+
prints the accepted object. Use a fresh run directory for another input.
|
|
187
|
+
|
|
188
|
+
### Run a review and repair workflow
|
|
189
|
+
|
|
190
|
+
```sh
|
|
191
|
+
.venv/bin/prosaic-harness run examples/tokenproxy-review.yml \
|
|
192
|
+
--checks examples/checks.py --input examples/request.json --run-dir runs/launch-review
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
This exercises four tiers: Ornith briefs the request, Qwen drafts a recommendation,
|
|
196
|
+
DeepSeek reviews it, and Nemotron creates a final decision. A gate routes an
|
|
197
|
+
unapproved review back to the author. The author receives the previous review
|
|
198
|
+
as an identified input artifact. The actual final decision gets its own model
|
|
199
|
+
review and deterministic evidence check before pausing for human approval:
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
.venv/bin/prosaic-harness resume examples/tokenproxy-review.yml \
|
|
203
|
+
--checks examples/checks.py --run-dir runs/launch-review --choice approve
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Choose `reject` to finish with a rejected outcome. Approval records a decision;
|
|
207
|
+
it does not publish files or send messages. Use `examples/review.yml` for your
|
|
208
|
+
own configured endpoint. See [examples/README.md](examples/README.md) for the
|
|
209
|
+
graph, contracts, tool example, and a complete Python embedding program.
|
|
210
|
+
|
|
211
|
+
## Workflow format
|
|
212
|
+
|
|
213
|
+
All paths in a workflow are relative to its directory and confined to it. The
|
|
214
|
+
workflow can be launched from any working directory. Schema references are
|
|
215
|
+
internal to their document. Arbitrary expressions and remote schema fetching
|
|
216
|
+
are not supported.
|
|
217
|
+
|
|
218
|
+
```yaml
|
|
219
|
+
version: 1
|
|
220
|
+
source: .prosaic
|
|
221
|
+
runtime: runtime.yml
|
|
222
|
+
start: draft
|
|
223
|
+
limits:
|
|
224
|
+
max_calls: 8
|
|
225
|
+
max_visits: 3
|
|
226
|
+
timeout_s: 180
|
|
227
|
+
steps:
|
|
228
|
+
draft:
|
|
229
|
+
kind: agent
|
|
230
|
+
agent: subagents/author.md
|
|
231
|
+
schema: schemas/draft.json
|
|
232
|
+
optional_inputs: [review]
|
|
233
|
+
max_attempts: 2
|
|
234
|
+
next: review
|
|
235
|
+
review:
|
|
236
|
+
kind: agent
|
|
237
|
+
agent: subagents/reviewer.md
|
|
238
|
+
schema: schemas/review.json
|
|
239
|
+
inputs: [draft]
|
|
240
|
+
next: gate
|
|
241
|
+
gate:
|
|
242
|
+
kind: gate
|
|
243
|
+
from: review
|
|
244
|
+
field: [approved]
|
|
245
|
+
equals: true
|
|
246
|
+
pass: done
|
|
247
|
+
fail: draft
|
|
248
|
+
done:
|
|
249
|
+
kind: finish
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Agent `arguments` are a JSON object with `request` (the run input), `artifacts`
|
|
253
|
+
(selected prior accepted outputs, keyed by step ID), and `validation_feedback`
|
|
254
|
+
(the last validation error, if any). `inputs` are required; `optional_inputs`
|
|
255
|
+
include an output only when it exists, allowing first-pass review loops.
|
|
256
|
+
Outputs replace a step's latest accepted value on revisits, while every attempt
|
|
257
|
+
is retained in receipts and approvals bind to exact required-input versions.
|
|
258
|
+
Optional inputs can carry stale feedback, not required approval dependencies.
|
|
259
|
+
Arguments also include `artifact_bindings` and declared file `sources`.
|
|
260
|
+
Raw transport stdout must be one JSON value; a single
|
|
261
|
+
JSON Markdown fence is also accepted. Schema failures do not advance the graph.
|
|
262
|
+
|
|
263
|
+
| Step kind | Fields and behavior |
|
|
264
|
+
| --- | --- |
|
|
265
|
+
| `agent` | `agent`, `schema`, `next`; optional `acquisition` prose ID, input IDs, tools/read roots, required successful tools, attempts, visits |
|
|
266
|
+
| `gate` | `from`, `field` (list of keys), `equals`, `pass`, `fail`; missing data blocks |
|
|
267
|
+
| `check` | `from`, trusted `validators`, `pass`, `fail`; no model call |
|
|
268
|
+
| `pause` | `question`, `choices` mapping named answers to next steps |
|
|
269
|
+
| `finish` | Optional `outcome: completed` or `rejected` |
|
|
270
|
+
|
|
271
|
+
A pause can optionally declare `response_schema: schemas/feedback.json` and
|
|
272
|
+
host-registered `validators`. Submit `resume(choice="refine", response={"text": "..."})`
|
|
273
|
+
or CLI `resume ... --choice refine --response feedback.json`. The schema validates
|
|
274
|
+
the payload; trusted pause validators receive `{"choice": ..., "response": ...}`
|
|
275
|
+
with the original request and accepted artifacts in their check context. Applications
|
|
276
|
+
can verify dynamic candidate membership there without encoding product IDs into the
|
|
277
|
+
workflow graph. Invalid responses leave the pause untouched. Accepted responses are
|
|
278
|
+
sealed into history and subsequent agent arguments include `human_responses`, keyed
|
|
279
|
+
by pause step with its latest `choice` and `response`. They are user data, never tool
|
|
280
|
+
permissions. Existing choice-only pauses retain their original behavior and reject
|
|
281
|
+
payloads. A completed response cannot be submitted again.
|
|
282
|
+
Trusted downstream validators also receive these accepted values through
|
|
283
|
+
`CheckContext.human_responses`; they can enforce that a proposal matches the user's
|
|
284
|
+
selection rather than trusting a model's account of that selection.
|
|
285
|
+
|
|
286
|
+
`max_run_s` includes human waiting. Interactive applications should use an explicit
|
|
287
|
+
human expiry for a decision workflow and a separate bounded workflow for each model
|
|
288
|
+
turn; do not reuse a short model request timeout as a human response deadline.
|
|
289
|
+
|
|
290
|
+
Each step may override `max_visits`. Agent attempts bound validation/transport
|
|
291
|
+
retries within a visit; visits bound graph loops; `max_calls` bounds invocations
|
|
292
|
+
across the whole run, including authorized interrupted retries. `timeout_s` is
|
|
293
|
+
per invocation. Optional `max_tokens` counts all reported tokens and blocks on
|
|
294
|
+
unknown usage; `max_run_s` persists a whole-run deadline including human waiting.
|
|
295
|
+
There is no monetary guarantee. Finite graph visits also bound
|
|
296
|
+
non-agent loops. There is no automatic model escalation.
|
|
297
|
+
|
|
298
|
+
## Permissions and evidence
|
|
299
|
+
|
|
300
|
+
Default agent permissions are empty. A workflow step may declare read tools and
|
|
301
|
+
explicit `read_roots`; the runtime also intersects those with the prose's tools
|
|
302
|
+
and runtime configuration grants. Optional `require_tools: [read_file]` rejects
|
|
303
|
+
an output unless the invocation produced a successful tool event for that name;
|
|
304
|
+
it does not prove which file was read or whether the answer interpreted it correctly.
|
|
305
|
+
Declare `evidence` and `require_reads` for hash-bound complete-file read evidence.
|
|
306
|
+
Development-only `acquisition: subagents/evidence-acquisition.md` sends a short
|
|
307
|
+
Prosaic artifact before the full agent assignment. It requires `require_reads`
|
|
308
|
+
and Runtime `acquisition_v1`; both prose digests are part of the sealed workflow
|
|
309
|
+
fingerprint. One Runtime invocation owns both phases, their shared deadline,
|
|
310
|
+
usage and tool budget. Failed acquisition blocks without automatic repair or
|
|
311
|
+
fallback. Final JSON/schema/source checks still apply after successful reads.
|
|
312
|
+
Acquisition gets no final arguments; its own prose specifies the evidence path.
|
|
313
|
+
For model-independent acquisition, explicitly choose the no-tool
|
|
314
|
+
`preloaded-evidence.yml` blueprint instead: the controller supplies immutable
|
|
315
|
+
evidence text in `sources`. This is snapshot evidence, not a native tool receipt.
|
|
316
|
+
See the [step-by-step examples](examples/README.md#staged-acquisition-and-no-tool-preloading).
|
|
317
|
+
The [direct-read problem and staged-acquisition resolution](examples/tool-acquisition.md)
|
|
318
|
+
show how to keep a detailed answer contract out of the initial read phase and
|
|
319
|
+
verify the native receipt before analysis.
|
|
320
|
+
Trusted checks are explicitly supplied by the host through `validators=` or CLI
|
|
321
|
+
`--checks`. They execute Python with host permissions and are not sandboxed.
|
|
322
|
+
V0.2 has no shell checks, agent file writes,
|
|
323
|
+
publication effects, remote workers, or recursive agent dispatch. Application
|
|
324
|
+
integrations can be added through an explicit boundary in a later release.
|
|
325
|
+
|
|
326
|
+
Run evidence is local:
|
|
327
|
+
|
|
328
|
+
```text
|
|
329
|
+
runs/launch-review/
|
|
330
|
+
run.json # sole durable state authority, accepted outputs, history
|
|
331
|
+
run.lock # OS-backed lock prevents concurrent writers
|
|
332
|
+
attempts/<id>.json # arguments, raw result, token usage, model/tool events
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`--events` emits JSONL events and a final status report to stdout. Normal mode
|
|
336
|
+
prints status and a five-second heartbeat to stderr and accepted results to stdout.
|
|
337
|
+
Credentials remain in environment/secret files; run evidence contains supplied
|
|
338
|
+
inputs and model output, so give its directory the same protection as the inputs.
|
|
339
|
+
The harness does not redact arbitrary sensitive information supplied by users.
|
|
340
|
+
|
|
341
|
+
## Resume and interruption
|
|
342
|
+
|
|
343
|
+
```sh
|
|
344
|
+
.venv/bin/prosaic-harness resume examples/review.yml --checks examples/checks.py --run-dir runs/launch-review
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
The harness saves a pending invocation before contacting the runtime, then saves
|
|
348
|
+
its receipt before committing the accepted output and transition. If a receipt
|
|
349
|
+
survived, resume adopts it without making another request. If no receipt survived,
|
|
350
|
+
the run blocks with `interrupted_call`: the endpoint may already have processed
|
|
351
|
+
the request. Explicitly authorize another billable call with:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
.venv/bin/prosaic-harness resume examples/review.yml \
|
|
355
|
+
--checks examples/checks.py --run-dir runs/launch-review --retry-interrupted
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
This consumes another call slot. There is no exactly-once guarantee for model
|
|
359
|
+
calls or their tool activity. Definitions, schemas, inspected prose, and runtime
|
|
360
|
+
configuration and validator versions are fingerprinted; changes require a new
|
|
361
|
+
run. Declared evidence changes also reject resume. Credential rotation
|
|
362
|
+
through the same environment-variable name does not change the fingerprint.
|
|
363
|
+
Limit-exhausted runs remain blocked; start a new run with revised limits rather
|
|
364
|
+
than modifying stored state. State assumes trusted local storage, not adversarial
|
|
365
|
+
tampering. Checksums and structural checks detect corruption, not coordinated
|
|
366
|
+
forgery. New checkpoints are version 2; old runs need a new directory.
|
|
367
|
+
CLI exit codes: 0 completed/waiting, 1 blocked/rejected, 2 configuration
|
|
368
|
+
or usage error, 130 interrupted. Waiting is explicit, not final acceptance.
|
|
369
|
+
|
|
370
|
+
## Development
|
|
371
|
+
|
|
372
|
+
```sh
|
|
373
|
+
.venv/bin/python -m pip install -e '.[test]'
|
|
374
|
+
.venv/bin/python -m pytest
|
|
375
|
+
.venv/bin/python -m build
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Tests cover schema retries, branching/repair, human choices, bounds, interrupted
|
|
379
|
+
calls, receipt recovery, definition changes, locking, tool scope, and transport
|
|
380
|
+
integration. Live runs are opt-in examples, not part of the offline suite.
|
|
381
|
+
|
|
382
|
+
## Structured JSON tools
|
|
383
|
+
|
|
384
|
+
This revision pins Prosaic Runtime 0.7.1, which supplies `StructuredToolLoop` for
|
|
385
|
+
explicit JSON tool-request transport. Product adapters can yield one Runtime
|
|
386
|
+
turn per Harness invocation while retaining application-owned result validators.
|
|
387
|
+
Register the same `CustomTool` descriptors with the workflow and adapter so
|
|
388
|
+
Harness fingerprints and checks their contracts. Harness retains routing and
|
|
389
|
+
checkpoint ownership; Runtime owns parsing, dispatch, bounds and repeat detection.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
b3_prosaic_harness-0.7.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
2
|
+
b3_prosaic_harness-0.7.1.dist-info/licenses/NOTICE,sha256=ElUIgB9aqeWDj68Un0FliVam9tItd9kKPum77UrCD8s,258
|
|
3
|
+
prosaic_harness/__init__.py,sha256=bhMi273a_Wf9aAJvlTiYGQ1vl2_utfFvEWC13l5oZkI,1384
|
|
4
|
+
prosaic_harness/admission_data.py,sha256=Yc5SVJ7xQhF4LPLgdgtiJMJ2oQVHiY2iXExz3sDVDYg,7093
|
|
5
|
+
prosaic_harness/bundles.py,sha256=YV_HQ9MRlzkryEgInv2ghX6seYIZOCQoZg_yoQgzZvw,5249
|
|
6
|
+
prosaic_harness/cli.py,sha256=xWK46mBeX_6sReQRwQ51qlUzfqC6nq0UbHDZuWLDq0k,4905
|
|
7
|
+
prosaic_harness/contracts.py,sha256=xA7BP4QM7lrbCDWquoCGEwuQRsr0sPr1I9_e53y2i9s,10116
|
|
8
|
+
prosaic_harness/discovery.py,sha256=mTIYQdYfzMS-KjZwmc_Uhv7CeiXDfN2xFgJygv8a714,10316
|
|
9
|
+
prosaic_harness/engine.py,sha256=YeErdW5LBRLaM4C60vP5UmfX8on5ZW858JCgIQGlBWY,51292
|
|
10
|
+
prosaic_harness/errors.py,sha256=5EGZeUsGp2lesttJe2Wx4YqsnHLlzQbts1Q9-iY9Kx0,4681
|
|
11
|
+
prosaic_harness/factory.py,sha256=KpVVn_Yo9Rqgp5hcKWeI_0ht0lABCZtgQKsqFyfiFZs,37478
|
|
12
|
+
prosaic_harness/file_store.py,sha256=OhcViBkJ7-Rn-YwD6glUE6GKKqvC5-E4WusHPVbmJrM,6233
|
|
13
|
+
prosaic_harness/graph_admission.py,sha256=ueY5sd7xwByPhRTZDdYsXk_vRQpUB3vQU7FmcT0jmlU,11492
|
|
14
|
+
prosaic_harness/interaction.py,sha256=hyZwZ5pSRXrv5vjqM2sd_CPb4Ph9c9FoapfiTVUq98g,3471
|
|
15
|
+
prosaic_harness/observations.py,sha256=AaJgq4Rh93xLSCvhJm0PGCyv_5X9qgOHIKStCvw951o,1917
|
|
16
|
+
prosaic_harness/run_store.py,sha256=d7PhDkZRLtByhLW-8ULB9c-zG12h1amj7dtb9Z2ke2I,4023
|
|
17
|
+
prosaic_harness/schema_validation.py,sha256=jjmUe6Qv9OgN15LjpfCwqDYvT_Af8MAiL93IuUZGOxg,10025
|
|
18
|
+
prosaic_harness/store.py,sha256=w66w9nH4nYILfmSubEvLBuXDTt02epjEEulUKmhqa7k,3868
|
|
19
|
+
prosaic_harness/testing.py,sha256=dX7Oxn__WmypWxyBAsD9I4w1ard3ZqKBUwYpHlV5CT8,1510
|
|
20
|
+
prosaic_harness/validation.py,sha256=O5B4umfq5mEslxM6FU_SOQx-RBuk-AWf_S1ALQVbUiw,1304
|
|
21
|
+
prosaic_harness/workflow.py,sha256=nVU97lIRTnm2tEvIcTQJSObRBQWTWqU6hdo4tIiC54Y,16888
|
|
22
|
+
b3_prosaic_harness-0.7.1.dist-info/METADATA,sha256=wWPgDlTCP083MlpOw6KKXloRZr3HFbw9-y3mVQbEw4w,19450
|
|
23
|
+
b3_prosaic_harness-0.7.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
24
|
+
b3_prosaic_harness-0.7.1.dist-info/entry_points.txt,sha256=CR2CL_4Kb9YKSK1SrSzHqJECPy63kbE7a9srlpzxmbI,61
|
|
25
|
+
b3_prosaic_harness-0.7.1.dist-info/top_level.txt,sha256=2SMWGxeYTQhYbvdWcYrRmdgqh2yq2ew4wUHlGgjC0jE,16
|
|
26
|
+
b3_prosaic_harness-0.7.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prosaic_harness
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Durable, validated execution around Prosaic Runtime."""
|
|
2
|
+
__version__ = '0.7.1'
|
|
3
|
+
|
|
4
|
+
from .engine import Harness
|
|
5
|
+
from .workflow import Workflow
|
|
6
|
+
from .factory import WorkflowCatalog, WorkflowBindings, WorkflowPolicy, WorkflowFactory
|
|
7
|
+
from .bundles import WorkflowBundle, WorkflowReference, PreparedWorkflow
|
|
8
|
+
from .errors import WorkflowAdmissionError, HumanResponseError
|
|
9
|
+
from .interaction import PendingInteraction
|
|
10
|
+
from .validation import Validator, CheckContext
|
|
11
|
+
from .file_store import FileRunStore
|
|
12
|
+
from .run_store import (RunStore, RunSnapshot, LeaseSession, StoreError, StoreUninitialized,
|
|
13
|
+
StoreIncompatible, StoreUnavailable, StoreBusy, RunBusy, LeaseLost,
|
|
14
|
+
RevisionConflict, ReceiptConflict, RunNotFound, RunAlreadyExists, StoreCorrupt)
|
|
15
|
+
|
|
16
|
+
__all__ = ['Harness', 'Workflow', 'Validator', 'CheckContext', 'FileRunStore', 'RunStore',
|
|
17
|
+
'RunSnapshot', 'LeaseSession', 'StoreError', 'StoreUninitialized', 'StoreIncompatible',
|
|
18
|
+
'StoreUnavailable', 'StoreBusy', 'RunBusy', 'LeaseLost', 'RevisionConflict',
|
|
19
|
+
'ReceiptConflict', 'RunNotFound', 'RunAlreadyExists', 'StoreCorrupt']
|
|
20
|
+
__all__ += ['WorkflowCatalog', 'WorkflowBindings', 'WorkflowPolicy', 'WorkflowFactory',
|
|
21
|
+
'WorkflowAdmissionError', 'HumanResponseError', 'PendingInteraction']
|
|
22
|
+
__all__ += ['WorkflowBundle', 'WorkflowReference', 'PreparedWorkflow']
|