hebbrix 2.6.0rc5__tar.gz → 2.6.2__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.
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/CHANGELOG.md +21 -0
- {hebbrix-2.6.0rc5/hebbrix.egg-info → hebbrix-2.6.2}/PKG-INFO +76 -36
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/README.md +72 -32
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/__init__.py +3 -2
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/_advice.py +55 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/chat.py +22 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/client.py +5 -1
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/models.py +16 -1
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/resources.py +69 -7
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/sync_client.py +62 -9
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2/hebbrix.egg-info}/PKG-INFO +76 -36
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix.egg-info/SOURCES.txt +1 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix.egg-info/requires.txt +1 -1
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/pyproject.toml +4 -4
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_advisor_integrity.py +22 -0
- hebbrix-2.6.2/tests/test_customer_developer_experience.py +167 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_outcome_advice_resource.py +20 -0
- hebbrix-2.6.2/tests/test_release_version.py +22 -0
- hebbrix-2.6.0rc5/tests/test_release_version.py +0 -12
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/LICENSE +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/MANIFEST.in +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/contracts/openapi-routes.json +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/docs/native-experience-operations.md +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/examples/native_reflection_worker.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/exceptions.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/execution.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/experience.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/openai_reflection.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/reflection_worker.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix/workflow.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix.egg-info/dependency_links.txt +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix.egg-info/entry_points.txt +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/hebbrix.egg-info/top_level.txt +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/setup.cfg +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_advanced_resources.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_evidence_loop_resource.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_evidence_safety_boundary.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_execution_permission.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_experience_request.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_experience_workflow.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_followup_helpers.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_memories_resource.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_openai_reflection.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_openapi_parity.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_procedural_resource.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_reflection_worker_cli.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_sync_client.py +0 -0
- {hebbrix-2.6.0rc5 → hebbrix-2.6.2}/tests/test_workflow_route_contract.py +0 -0
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.6.2 — 2026-10-06 (compact advice, batches and confirmation)
|
|
4
|
+
|
|
5
|
+
- Correct canonical documentation metadata and simplify the stable three-call guide.
|
|
6
|
+
- Add optional compact search/advice, bounded independently committed decision/outcome batches, and explicit caller-confirmation transports.
|
|
7
|
+
- Add bounded chat-learning wait options while preserving the original job receipt.
|
|
8
|
+
- Keep historical confidence scope aliases, ACT-as-advice and protected outcome boundaries intact.
|
|
9
|
+
- Requires matching Round9 server routes; no benchmark superiority, latency SLA or automatic execution is implied.
|
|
10
|
+
|
|
11
|
+
## 2.6.1 — 2026-10-04 (advisory horizon helpers)
|
|
12
|
+
|
|
13
|
+
- Carry optional remaining_decisions and max_pilot_decisions through evidence reads and the once-only advisor callback.
|
|
14
|
+
- Keep actual caller distribution validation, owner scope and observe-mode logging unchanged.
|
|
15
|
+
- New backend v3 controls remain explicit experimental opt-ins; these helpers do not execute actions or establish performance, calibration or superiority.
|
|
16
|
+
|
|
17
|
+
## 2.6.0 — 2026-10-04 (stable SDK)
|
|
18
|
+
|
|
19
|
+
- Bound runtime HTTPX to `>=0.25.0,<1`, excluding incompatible 1.x prereleases.
|
|
20
|
+
- Add sync/async atomic setup options for explicit policy configuration and built-in success-minus-cost metrics.
|
|
21
|
+
- Keep advisor input/probability validation, scope and protected evidence transports unchanged.
|
|
22
|
+
- Backend v3 learning methods remain explicit experimental opt-ins. Stable packaging does not establish performance, calibrated confidence or execution permission.
|
|
23
|
+
|
|
3
24
|
## 2.6.0rc5 — 2026-10-03 (prerelease)
|
|
4
25
|
|
|
5
26
|
- Snapshot advisor context/candidates and reject scope overrides or mutable identities.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hebbrix
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.2
|
|
4
4
|
Summary: Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs
|
|
5
5
|
Author-email: Hebbrix Team <support@hebbrix.com>
|
|
6
6
|
Maintainer-email: Hebbrix Team <support@hebbrix.com>
|
|
@@ -27,13 +27,13 @@ License: MIT License
|
|
|
27
27
|
SOFTWARE.
|
|
28
28
|
|
|
29
29
|
Project-URL: Homepage, https://hebbrix.com
|
|
30
|
-
Project-URL: Documentation, https://
|
|
30
|
+
Project-URL: Documentation, https://hebbrix.com/docs
|
|
31
31
|
Project-URL: Source, https://github.com/Hebbrix/hebbrix-python
|
|
32
32
|
Project-URL: Issues, https://github.com/Hebbrix/hebbrix-python/issues
|
|
33
33
|
Project-URL: Support, https://www.hebbrix.com/contact
|
|
34
34
|
Project-URL: API Reference, https://api.hebbrix.com/docs
|
|
35
35
|
Keywords: ai,memory,agents,llm,chatbot,assistant,ml,reinforcement-learning,knowledge-graph,vector-search,rag,temporal,procedural-memory,working-memory
|
|
36
|
-
Classifier: Development Status ::
|
|
36
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
37
37
|
Classifier: Intended Audience :: Developers
|
|
38
38
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
39
39
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
@@ -49,7 +49,7 @@ Classifier: Framework :: AsyncIO
|
|
|
49
49
|
Requires-Python: >=3.8
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
License-File: LICENSE
|
|
52
|
-
Requires-Dist: httpx
|
|
52
|
+
Requires-Dist: httpx<1,>=0.25.0
|
|
53
53
|
Requires-Dist: requests>=2.31.0
|
|
54
54
|
Provides-Extra: dev
|
|
55
55
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
@@ -65,45 +65,23 @@ Dynamic: license-file
|
|
|
65
65
|
|
|
66
66
|
Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
an action still requires independent permission.
|
|
68
|
+
The current stable package is **2.6.2**. Start with memory storage and search, or
|
|
69
|
+
the three-call outcome-learning workflow below. Advanced evidence and execution
|
|
70
|
+
permission transports are opt-in; installing the SDK never permits an action.
|
|
72
71
|
|
|
73
72
|
## Install
|
|
74
73
|
|
|
75
74
|
```bash
|
|
76
|
-
pip install hebbrix==2.6.
|
|
75
|
+
pip install hebbrix==2.6.2
|
|
77
76
|
```
|
|
78
77
|
|
|
79
78
|
Python 3.8+ is supported. `MemoryClient` is asynchronous. `SyncMemoryClient`
|
|
80
79
|
supports the core collection, memory, search, correction, procedure, and
|
|
81
|
-
|
|
80
|
+
outcome-learning workflows; advanced temporal, working-memory, consolidation,
|
|
82
81
|
memory-tool, and RL resources are currently async-only.
|
|
83
82
|
|
|
84
83
|
## Quick start
|
|
85
84
|
|
|
86
|
-
October 2 follow-up: `proofloop.setup_policy` atomically creates a new
|
|
87
|
-
context/schema policy with explicitly declared low-risk exploration; existing
|
|
88
|
-
policies are not migrated automatically. `learning_report` reads a bounded,
|
|
89
|
-
scoped descriptive report, not proven uplift. `decide_with_advice` reads an
|
|
90
|
-
evidence card, invokes the supplied advisor once and logs its actual choice and
|
|
91
|
-
probabilities. `decide` accepts bounded `prior_action` / `prior_strength` for one
|
|
92
|
-
server-selected decision; this is not outcome evidence. These new helpers and
|
|
93
|
-
structured paraphrase matching require the matching October 2 outcome-followup
|
|
94
|
-
backend, not merely its database schema; inspect `/v1/release` before use.
|
|
95
|
-
Nothing here grants permission to execute. Learning performance and reliable
|
|
96
|
-
model compliance with feedback are not established.
|
|
97
|
-
|
|
98
|
-
Both clients expose `proofloop.register_context_schema`, `context_schema`,
|
|
99
|
-
`configure_policy`, `policy_configuration`, `policy_advice` and `action_advice`.
|
|
100
|
-
Enroll context before recording decisions. Configuration uses `expected_revision`
|
|
101
|
-
for compare-and-swap; do not retry a conflict blindly. Exploration remains an
|
|
102
|
-
explicit low-risk opt-in. `action_advice` takes the exact configured description,
|
|
103
|
-
policy/action IDs and context, and maps `user_id` to the confidence endpoint's
|
|
104
|
-
`end_user_id`. For the complete request shapes, see the
|
|
105
|
-
[learning guide](https://www.hebbrix.com/docs/learning).
|
|
106
|
-
|
|
107
85
|
```python
|
|
108
86
|
import asyncio
|
|
109
87
|
from hebbrix import MemoryClient
|
|
@@ -126,6 +104,57 @@ async def main():
|
|
|
126
104
|
asyncio.run(main())
|
|
127
105
|
```
|
|
128
106
|
|
|
107
|
+
## Learn from outcomes in three calls
|
|
108
|
+
|
|
109
|
+
Use server-side selection when Hebbrix should choose. Read-only advice is for a
|
|
110
|
+
caller that intentionally chooses outside Hebbrix; an LLM can ignore that advice.
|
|
111
|
+
Configure a new policy once, request a decision, then report its actual result:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
await client.proofloop.setup_policy(
|
|
115
|
+
"support.reply.v1", user_id="customer-42",
|
|
116
|
+
context_schema={"version": "v1", "fields": {
|
|
117
|
+
"issue": {"values": ["delivery", "billing"], "required": True}
|
|
118
|
+
}},
|
|
119
|
+
actions={
|
|
120
|
+
"explain": {"description": "Explain the delivery status", "target": "ticket",
|
|
121
|
+
"risk_tier": "low", "exploration_allowed": True},
|
|
122
|
+
"review": {"description": "Request a support review", "target": "ticket",
|
|
123
|
+
"risk_tier": "low", "exploration_allowed": True},
|
|
124
|
+
},
|
|
125
|
+
configuration={"strategy": "posterior_sampling"},
|
|
126
|
+
)
|
|
127
|
+
decision = await client.proofloop.decide(
|
|
128
|
+
policy_key="support.reply.v1", user_id="customer-42", mode="auto",
|
|
129
|
+
context={"issue": "delivery"},
|
|
130
|
+
candidates=[{"action_key": "explain"}, {"action_key": "review"}],
|
|
131
|
+
idempotency_key="ticket-42-decision",
|
|
132
|
+
)
|
|
133
|
+
# Your application checks permission and performs the action separately.
|
|
134
|
+
# Here success is the actual result supplied by that application, not a prediction.
|
|
135
|
+
await client.proofloop.record_outcome(
|
|
136
|
+
decision["decision_id"], success=success,
|
|
137
|
+
idempotency_key="ticket-42-result",
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`success` must come from your application or an independently authorized
|
|
142
|
+
verifier. Do not report the recommendation itself as a successful execution.
|
|
143
|
+
Keep action identities and required context stable. Use a new policy/version
|
|
144
|
+
when changing what an action or outcome means. See the
|
|
145
|
+
[recommended defaults](https://hebbrix.com/docs/learning).
|
|
146
|
+
|
|
147
|
+
## Advice and integration boundaries
|
|
148
|
+
|
|
149
|
+
`proofloop.action_advice(...)` reads the exact configured action and context.
|
|
150
|
+
The canonical `gate` is `ASK`, `REVIEW`, `ACT`, or `BLOCK`. `BLOCK` dominates;
|
|
151
|
+
`ACT` is advice, not permission. Apply your own current authorization and human
|
|
152
|
+
approval policy before executing any tool. Do not infer permission from a score.
|
|
153
|
+
|
|
154
|
+
Version 2.6.2 adds compact advice, batch, and explicit confirmation helpers.
|
|
155
|
+
They require matching Round9 server routes. Compact views retain scope and safety
|
|
156
|
+
caveats; complete receipts remain on the server.
|
|
157
|
+
|
|
129
158
|
## Durable readiness
|
|
130
159
|
|
|
131
160
|
Memory writes return either a searchable completion or a durable `202` receipt.
|
|
@@ -206,7 +235,7 @@ The production API publishes exact build and artifact compatibility at
|
|
|
206
235
|
[`GET /v1/release`](https://api.hebbrix.com/v1/release). The public OpenAPI is
|
|
207
236
|
[`/openapi.json`](https://api.hebbrix.com/openapi.json).
|
|
208
237
|
|
|
209
|
-
- [Documentation](https://
|
|
238
|
+
- [Documentation](https://hebbrix.com/docs)
|
|
210
239
|
- [API reference](https://api.hebbrix.com/docs)
|
|
211
240
|
- [PyPI files](https://pypi.org/project/hebbrix/#files)
|
|
212
241
|
- [Support](https://www.hebbrix.com/contact)
|
|
@@ -214,14 +243,25 @@ The production API publishes exact build and artifact compatibility at
|
|
|
214
243
|
## License
|
|
215
244
|
|
|
216
245
|
MIT. See `LICENSE` in the distribution.
|
|
217
|
-
##
|
|
246
|
+
## Advanced evidence workflows
|
|
218
247
|
|
|
219
248
|
The current source includes `client.experiences`, bounded reflection workers,
|
|
220
249
|
separate lesson review/revision and explicit one-use execution admission. These
|
|
221
|
-
methods require the
|
|
222
|
-
|
|
250
|
+
methods require the server's published compatibility contract and separately
|
|
251
|
+
scoped credentials. The package supplies `hebbrix-reflect --help`.
|
|
223
252
|
Importing it does not call a model, approve a lesson or execute a tool.
|
|
224
253
|
|
|
225
|
-
See
|
|
254
|
+
See the [documentation](https://hebbrix.com/docs) for role scopes,
|
|
226
255
|
uncertain-call recovery, exact-request binding and policy rollback. Do not treat a
|
|
227
256
|
lesson, score, review or issued permit as execution permission.
|
|
257
|
+
|
|
258
|
+
## Stability
|
|
259
|
+
|
|
260
|
+
Stable SDK versions follow semantic versioning. Patch updates correct defects;
|
|
261
|
+
new optional fields and methods are additive. Existing required context, action
|
|
262
|
+
identity, owner scope, and historical outcomes are not silently rewritten.
|
|
263
|
+
Experimental APIs are marked separately. Security and correctness guards may
|
|
264
|
+
be tightened immediately; migrations and other incompatible changes must be
|
|
265
|
+
documented with their supported replacement. Read [CHANGELOG.md](CHANGELOG.md)
|
|
266
|
+
before upgrading and pin versions in production. Release cadence is not a
|
|
267
|
+
performance, compliance, or reliability guarantee.
|
|
@@ -2,45 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
an action still requires independent permission.
|
|
5
|
+
The current stable package is **2.6.2**. Start with memory storage and search, or
|
|
6
|
+
the three-call outcome-learning workflow below. Advanced evidence and execution
|
|
7
|
+
permission transports are opt-in; installing the SDK never permits an action.
|
|
9
8
|
|
|
10
9
|
## Install
|
|
11
10
|
|
|
12
11
|
```bash
|
|
13
|
-
pip install hebbrix==2.6.
|
|
12
|
+
pip install hebbrix==2.6.2
|
|
14
13
|
```
|
|
15
14
|
|
|
16
15
|
Python 3.8+ is supported. `MemoryClient` is asynchronous. `SyncMemoryClient`
|
|
17
16
|
supports the core collection, memory, search, correction, procedure, and
|
|
18
|
-
|
|
17
|
+
outcome-learning workflows; advanced temporal, working-memory, consolidation,
|
|
19
18
|
memory-tool, and RL resources are currently async-only.
|
|
20
19
|
|
|
21
20
|
## Quick start
|
|
22
21
|
|
|
23
|
-
October 2 follow-up: `proofloop.setup_policy` atomically creates a new
|
|
24
|
-
context/schema policy with explicitly declared low-risk exploration; existing
|
|
25
|
-
policies are not migrated automatically. `learning_report` reads a bounded,
|
|
26
|
-
scoped descriptive report, not proven uplift. `decide_with_advice` reads an
|
|
27
|
-
evidence card, invokes the supplied advisor once and logs its actual choice and
|
|
28
|
-
probabilities. `decide` accepts bounded `prior_action` / `prior_strength` for one
|
|
29
|
-
server-selected decision; this is not outcome evidence. These new helpers and
|
|
30
|
-
structured paraphrase matching require the matching October 2 outcome-followup
|
|
31
|
-
backend, not merely its database schema; inspect `/v1/release` before use.
|
|
32
|
-
Nothing here grants permission to execute. Learning performance and reliable
|
|
33
|
-
model compliance with feedback are not established.
|
|
34
|
-
|
|
35
|
-
Both clients expose `proofloop.register_context_schema`, `context_schema`,
|
|
36
|
-
`configure_policy`, `policy_configuration`, `policy_advice` and `action_advice`.
|
|
37
|
-
Enroll context before recording decisions. Configuration uses `expected_revision`
|
|
38
|
-
for compare-and-swap; do not retry a conflict blindly. Exploration remains an
|
|
39
|
-
explicit low-risk opt-in. `action_advice` takes the exact configured description,
|
|
40
|
-
policy/action IDs and context, and maps `user_id` to the confidence endpoint's
|
|
41
|
-
`end_user_id`. For the complete request shapes, see the
|
|
42
|
-
[learning guide](https://www.hebbrix.com/docs/learning).
|
|
43
|
-
|
|
44
22
|
```python
|
|
45
23
|
import asyncio
|
|
46
24
|
from hebbrix import MemoryClient
|
|
@@ -63,6 +41,57 @@ async def main():
|
|
|
63
41
|
asyncio.run(main())
|
|
64
42
|
```
|
|
65
43
|
|
|
44
|
+
## Learn from outcomes in three calls
|
|
45
|
+
|
|
46
|
+
Use server-side selection when Hebbrix should choose. Read-only advice is for a
|
|
47
|
+
caller that intentionally chooses outside Hebbrix; an LLM can ignore that advice.
|
|
48
|
+
Configure a new policy once, request a decision, then report its actual result:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
await client.proofloop.setup_policy(
|
|
52
|
+
"support.reply.v1", user_id="customer-42",
|
|
53
|
+
context_schema={"version": "v1", "fields": {
|
|
54
|
+
"issue": {"values": ["delivery", "billing"], "required": True}
|
|
55
|
+
}},
|
|
56
|
+
actions={
|
|
57
|
+
"explain": {"description": "Explain the delivery status", "target": "ticket",
|
|
58
|
+
"risk_tier": "low", "exploration_allowed": True},
|
|
59
|
+
"review": {"description": "Request a support review", "target": "ticket",
|
|
60
|
+
"risk_tier": "low", "exploration_allowed": True},
|
|
61
|
+
},
|
|
62
|
+
configuration={"strategy": "posterior_sampling"},
|
|
63
|
+
)
|
|
64
|
+
decision = await client.proofloop.decide(
|
|
65
|
+
policy_key="support.reply.v1", user_id="customer-42", mode="auto",
|
|
66
|
+
context={"issue": "delivery"},
|
|
67
|
+
candidates=[{"action_key": "explain"}, {"action_key": "review"}],
|
|
68
|
+
idempotency_key="ticket-42-decision",
|
|
69
|
+
)
|
|
70
|
+
# Your application checks permission and performs the action separately.
|
|
71
|
+
# Here success is the actual result supplied by that application, not a prediction.
|
|
72
|
+
await client.proofloop.record_outcome(
|
|
73
|
+
decision["decision_id"], success=success,
|
|
74
|
+
idempotency_key="ticket-42-result",
|
|
75
|
+
)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`success` must come from your application or an independently authorized
|
|
79
|
+
verifier. Do not report the recommendation itself as a successful execution.
|
|
80
|
+
Keep action identities and required context stable. Use a new policy/version
|
|
81
|
+
when changing what an action or outcome means. See the
|
|
82
|
+
[recommended defaults](https://hebbrix.com/docs/learning).
|
|
83
|
+
|
|
84
|
+
## Advice and integration boundaries
|
|
85
|
+
|
|
86
|
+
`proofloop.action_advice(...)` reads the exact configured action and context.
|
|
87
|
+
The canonical `gate` is `ASK`, `REVIEW`, `ACT`, or `BLOCK`. `BLOCK` dominates;
|
|
88
|
+
`ACT` is advice, not permission. Apply your own current authorization and human
|
|
89
|
+
approval policy before executing any tool. Do not infer permission from a score.
|
|
90
|
+
|
|
91
|
+
Version 2.6.2 adds compact advice, batch, and explicit confirmation helpers.
|
|
92
|
+
They require matching Round9 server routes. Compact views retain scope and safety
|
|
93
|
+
caveats; complete receipts remain on the server.
|
|
94
|
+
|
|
66
95
|
## Durable readiness
|
|
67
96
|
|
|
68
97
|
Memory writes return either a searchable completion or a durable `202` receipt.
|
|
@@ -143,7 +172,7 @@ The production API publishes exact build and artifact compatibility at
|
|
|
143
172
|
[`GET /v1/release`](https://api.hebbrix.com/v1/release). The public OpenAPI is
|
|
144
173
|
[`/openapi.json`](https://api.hebbrix.com/openapi.json).
|
|
145
174
|
|
|
146
|
-
- [Documentation](https://
|
|
175
|
+
- [Documentation](https://hebbrix.com/docs)
|
|
147
176
|
- [API reference](https://api.hebbrix.com/docs)
|
|
148
177
|
- [PyPI files](https://pypi.org/project/hebbrix/#files)
|
|
149
178
|
- [Support](https://www.hebbrix.com/contact)
|
|
@@ -151,14 +180,25 @@ The production API publishes exact build and artifact compatibility at
|
|
|
151
180
|
## License
|
|
152
181
|
|
|
153
182
|
MIT. See `LICENSE` in the distribution.
|
|
154
|
-
##
|
|
183
|
+
## Advanced evidence workflows
|
|
155
184
|
|
|
156
185
|
The current source includes `client.experiences`, bounded reflection workers,
|
|
157
186
|
separate lesson review/revision and explicit one-use execution admission. These
|
|
158
|
-
methods require the
|
|
159
|
-
|
|
187
|
+
methods require the server's published compatibility contract and separately
|
|
188
|
+
scoped credentials. The package supplies `hebbrix-reflect --help`.
|
|
160
189
|
Importing it does not call a model, approve a lesson or execute a tool.
|
|
161
190
|
|
|
162
|
-
See
|
|
191
|
+
See the [documentation](https://hebbrix.com/docs) for role scopes,
|
|
163
192
|
uncertain-call recovery, exact-request binding and policy rollback. Do not treat a
|
|
164
193
|
lesson, score, review or issued permit as execution permission.
|
|
194
|
+
|
|
195
|
+
## Stability
|
|
196
|
+
|
|
197
|
+
Stable SDK versions follow semantic versioning. Patch updates correct defects;
|
|
198
|
+
new optional fields and methods are additive. Existing required context, action
|
|
199
|
+
identity, owner scope, and historical outcomes are not silently rewritten.
|
|
200
|
+
Experimental APIs are marked separately. Security and correctness guards may
|
|
201
|
+
be tightened immediately; migrations and other incompatible changes must be
|
|
202
|
+
documented with their supported replacement. Read [CHANGELOG.md](CHANGELOG.md)
|
|
203
|
+
before upgrading and pin versions in production. Release cadence is not a
|
|
204
|
+
performance, compliance, or reliability guarantee.
|
|
@@ -5,7 +5,7 @@ production OpenAPI and ``GET /v1/users/me/capabilities``. The experimental
|
|
|
5
5
|
World Model is intentionally absent from this release.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "2.6.
|
|
8
|
+
__version__ = "2.6.2"
|
|
9
9
|
__author__ = "Hebbrix Team"
|
|
10
10
|
__license__ = "MIT"
|
|
11
11
|
|
|
@@ -21,7 +21,7 @@ from hebbrix.exceptions import (
|
|
|
21
21
|
ServerError,
|
|
22
22
|
ValidationError,
|
|
23
23
|
)
|
|
24
|
-
from hebbrix.models import EvidenceClaim, GroundingReceipt, SearchSafetyEnvelope
|
|
24
|
+
from hebbrix.models import ActionAdviceReceipt, EvidenceClaim, GroundingReceipt, SearchSafetyEnvelope
|
|
25
25
|
from hebbrix.sync_client import SyncMemoryClient
|
|
26
26
|
|
|
27
27
|
__all__ = [
|
|
@@ -39,4 +39,5 @@ __all__ = [
|
|
|
39
39
|
"GroundingReceipt",
|
|
40
40
|
"EvidenceClaim",
|
|
41
41
|
"SearchSafetyEnvelope",
|
|
42
|
+
"ActionAdviceReceipt",
|
|
42
43
|
]
|
|
@@ -5,6 +5,61 @@ import math
|
|
|
5
5
|
import re
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
def _validate_advice_view(view):
|
|
9
|
+
if view is not None and view not in ("full", "compact"):
|
|
10
|
+
raise ValueError("view must be full or compact")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _confirmation_payload(observation_id, idempotency_key, success, confirmed,
|
|
14
|
+
collection_id=None, user_id=None, source_system=None,
|
|
15
|
+
source_event_id=None, evidence_digest=None):
|
|
16
|
+
if type(success) is not bool or confirmed is not True:
|
|
17
|
+
raise ValueError("explicit Boolean success and confirmed=True are required")
|
|
18
|
+
for field, value in (("observation_id", observation_id),
|
|
19
|
+
("idempotency_key", idempotency_key)):
|
|
20
|
+
if type(value) is not str or not value.strip() or len(value) > 160:
|
|
21
|
+
raise ValueError("{} must be a nonempty bounded string".format(field))
|
|
22
|
+
return {key: value for key, value in dict(
|
|
23
|
+
observation_id=observation_id, idempotency_key=idempotency_key,
|
|
24
|
+
success=success, confirmed=True, collection_id=collection_id, user_id=user_id,
|
|
25
|
+
source_system=source_system, source_event_id=source_event_id,
|
|
26
|
+
evidence_digest=evidence_digest,
|
|
27
|
+
).items() if value is not None}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _batch_payload(items, view="compact", outcomes=False):
|
|
31
|
+
_validate_advice_view(view)
|
|
32
|
+
if type(items) is not list or not 1 <= len(items) <= 50:
|
|
33
|
+
raise ValueError("batch items must contain 1-50 requests")
|
|
34
|
+
copied = _json_snapshot(items, "batch items", 4_000_000)
|
|
35
|
+
for item in copied:
|
|
36
|
+
if type(item) is not dict:
|
|
37
|
+
raise ValueError("each batch item must be an object")
|
|
38
|
+
key = item.get("idempotency_key")
|
|
39
|
+
if type(key) is not str or not key.strip() or len(key) > 160:
|
|
40
|
+
raise ValueError("each batch item needs a nonempty idempotency_key")
|
|
41
|
+
if outcomes and (type(item.get("decision_id")) is not str or
|
|
42
|
+
not item["decision_id"].strip() or
|
|
43
|
+
type(item.get("outcome")) is not dict):
|
|
44
|
+
raise ValueError("outcome items need decision_id and an outcome object")
|
|
45
|
+
if not outcomes and "proof_context" in item:
|
|
46
|
+
context = item.pop("proof_context")
|
|
47
|
+
token = context.get("token") if type(context) is dict else context
|
|
48
|
+
if type(token) is not str or not token.strip():
|
|
49
|
+
raise ValueError("proof_context must contain the original proof token")
|
|
50
|
+
if "proof_context_token" in item and item["proof_context_token"] != token:
|
|
51
|
+
raise ValueError("conflicting proof context tokens")
|
|
52
|
+
item["proof_context_token"] = token
|
|
53
|
+
return {"items": copied, **({"view": view} if view is not None else {})}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _validate_advisor_horizon(remaining_decisions, max_pilot_decisions):
|
|
57
|
+
for field, value, maximum in (("remaining_decisions", remaining_decisions, 10000),
|
|
58
|
+
("max_pilot_decisions", max_pilot_decisions, 8)):
|
|
59
|
+
if value is not None and (type(value) is not int or not 1 <= value <= maximum):
|
|
60
|
+
raise ValueError("{} must be an integer within the API limit".format(field))
|
|
61
|
+
|
|
62
|
+
|
|
8
63
|
def _validate_advisor_scope(policy_key, collection_id, user_id, idempotency_key):
|
|
9
64
|
if (
|
|
10
65
|
type(policy_key) is not str
|
|
@@ -11,11 +11,27 @@ Example:
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from typing import Any, Dict, List, Optional
|
|
14
|
+
import math
|
|
14
15
|
|
|
15
16
|
import requests
|
|
16
17
|
from hebbrix.client import MemoryClient
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
def _chat_readiness_options(wait_for_learning_seconds, include_low_confidence):
|
|
21
|
+
if (isinstance(wait_for_learning_seconds, bool) or
|
|
22
|
+
not isinstance(wait_for_learning_seconds, (int, float)) or
|
|
23
|
+
not math.isfinite(wait_for_learning_seconds) or
|
|
24
|
+
not 0 <= wait_for_learning_seconds <= 20):
|
|
25
|
+
raise ValueError("wait_for_learning_seconds must be between 0 and 20")
|
|
26
|
+
if type(include_low_confidence) is not bool:
|
|
27
|
+
raise ValueError("include_low_confidence must be explicitly Boolean")
|
|
28
|
+
return {
|
|
29
|
+
**({"wait_for_learning_seconds": wait_for_learning_seconds}
|
|
30
|
+
if wait_for_learning_seconds else {}),
|
|
31
|
+
**({"include_low_confidence": True} if include_low_confidence else {}),
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
19
35
|
class MemoryChat:
|
|
20
36
|
"""
|
|
21
37
|
Simple chat interface with automatic memory integration.
|
|
@@ -94,6 +110,8 @@ class MemoryChat:
|
|
|
94
110
|
session_id: str,
|
|
95
111
|
temperature: float = 0.7,
|
|
96
112
|
max_tokens: Optional[int] = None,
|
|
113
|
+
*, wait_for_learning_seconds: float = 0,
|
|
114
|
+
include_low_confidence: bool = False,
|
|
97
115
|
) -> str:
|
|
98
116
|
"""
|
|
99
117
|
Send a message and get a response with automatic memory integration.
|
|
@@ -122,6 +140,7 @@ class MemoryChat:
|
|
|
122
140
|
"prompt_strategy": self.prompt_strategy,
|
|
123
141
|
"memory_limit": self.memory_limit,
|
|
124
142
|
"temperature": temperature,
|
|
143
|
+
**_chat_readiness_options(wait_for_learning_seconds, include_low_confidence),
|
|
125
144
|
}
|
|
126
145
|
|
|
127
146
|
if max_tokens:
|
|
@@ -146,6 +165,8 @@ class MemoryChat:
|
|
|
146
165
|
session_id: str,
|
|
147
166
|
temperature: float = 0.7,
|
|
148
167
|
max_tokens: Optional[int] = None,
|
|
168
|
+
*, wait_for_learning_seconds: float = 0,
|
|
169
|
+
include_low_confidence: bool = False,
|
|
149
170
|
) -> Dict[str, Any]:
|
|
150
171
|
"""
|
|
151
172
|
Send a message and get full response with memory context.
|
|
@@ -176,6 +197,7 @@ class MemoryChat:
|
|
|
176
197
|
"prompt_strategy": self.prompt_strategy,
|
|
177
198
|
"memory_limit": self.memory_limit,
|
|
178
199
|
"temperature": temperature,
|
|
200
|
+
**_chat_readiness_options(wait_for_learning_seconds, include_low_confidence),
|
|
179
201
|
}
|
|
180
202
|
|
|
181
203
|
if max_tokens:
|
|
@@ -93,7 +93,7 @@ class MemoryClient:
|
|
|
93
93
|
"""Get request headers."""
|
|
94
94
|
headers = {
|
|
95
95
|
"Content-Type": "application/json",
|
|
96
|
-
"User-Agent": "hebbrix-python/2.6.
|
|
96
|
+
"User-Agent": "hebbrix-python/2.6.2",
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
if self.api_key:
|
|
@@ -254,6 +254,7 @@ class MemoryClient:
|
|
|
254
254
|
include_low_confidence: bool = False,
|
|
255
255
|
group_by_source: bool = True,
|
|
256
256
|
debug: bool = False,
|
|
257
|
+
view: Optional[str] = None,
|
|
257
258
|
) -> List[Dict[str, Any]]:
|
|
258
259
|
"""
|
|
259
260
|
Search memories.
|
|
@@ -282,6 +283,7 @@ class MemoryClient:
|
|
|
282
283
|
include_low_confidence=include_low_confidence,
|
|
283
284
|
group_by_source=group_by_source,
|
|
284
285
|
debug=debug,
|
|
286
|
+
view=view,
|
|
285
287
|
)
|
|
286
288
|
|
|
287
289
|
async def search_with_proof(
|
|
@@ -299,6 +301,7 @@ class MemoryClient:
|
|
|
299
301
|
include_low_confidence: bool = False,
|
|
300
302
|
group_by_source: bool = True,
|
|
301
303
|
debug: bool = False,
|
|
304
|
+
view: Optional[str] = None,
|
|
302
305
|
) -> Dict[str, Any]:
|
|
303
306
|
"""Search and return both results and the automatic ProofLoop context."""
|
|
304
307
|
|
|
@@ -316,6 +319,7 @@ class MemoryClient:
|
|
|
316
319
|
include_low_confidence=include_low_confidence,
|
|
317
320
|
group_by_source=group_by_source,
|
|
318
321
|
debug=debug,
|
|
322
|
+
view=view,
|
|
319
323
|
)
|
|
320
324
|
|
|
321
325
|
async def reason(
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
"""Public response contracts for evidence-bearing Hebbrix operations."""
|
|
2
2
|
|
|
3
|
-
from typing import Any, Dict, List, TypedDict
|
|
3
|
+
from typing import Any, Dict, List, TypedDict, Literal, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ActionAdviceReceipt(TypedDict, total=False):
|
|
7
|
+
"""Canonical advice envelope. ACT is never execution authorization."""
|
|
8
|
+
|
|
9
|
+
gate: Literal["ASK", "REVIEW", "ACT", "BLOCK"]
|
|
10
|
+
recommendation: str
|
|
11
|
+
recommended_action: str
|
|
12
|
+
action_confidence: Optional[float]
|
|
13
|
+
blocked_by: Optional[str]
|
|
14
|
+
blocked_hint: Optional[str]
|
|
15
|
+
autonomy_evidence: Dict[str, Any]
|
|
16
|
+
action_evidence: List[Dict[str, Any]]
|
|
17
|
+
authorization_granted: bool
|
|
18
|
+
execution_permission_required: bool
|
|
4
19
|
|
|
5
20
|
|
|
6
21
|
class GroundingReceipt(TypedDict, total=False):
|