hebbrix 2.6.1__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.
Files changed (47) hide show
  1. {hebbrix-2.6.1 → hebbrix-2.6.2}/CHANGELOG.md +8 -0
  2. {hebbrix-2.6.1/hebbrix.egg-info → hebbrix-2.6.2}/PKG-INFO +74 -43
  3. {hebbrix-2.6.1 → hebbrix-2.6.2}/README.md +72 -41
  4. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/__init__.py +3 -2
  5. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/_advice.py +48 -0
  6. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/chat.py +22 -0
  7. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/client.py +5 -1
  8. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/models.py +16 -1
  9. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/resources.py +56 -5
  10. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/sync_client.py +48 -6
  11. {hebbrix-2.6.1 → hebbrix-2.6.2/hebbrix.egg-info}/PKG-INFO +74 -43
  12. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix.egg-info/SOURCES.txt +1 -0
  13. {hebbrix-2.6.1 → hebbrix-2.6.2}/pyproject.toml +2 -2
  14. hebbrix-2.6.2/tests/test_customer_developer_experience.py +167 -0
  15. {hebbrix-2.6.1 → hebbrix-2.6.2}/LICENSE +0 -0
  16. {hebbrix-2.6.1 → hebbrix-2.6.2}/MANIFEST.in +0 -0
  17. {hebbrix-2.6.1 → hebbrix-2.6.2}/contracts/openapi-routes.json +0 -0
  18. {hebbrix-2.6.1 → hebbrix-2.6.2}/docs/native-experience-operations.md +0 -0
  19. {hebbrix-2.6.1 → hebbrix-2.6.2}/examples/native_reflection_worker.py +0 -0
  20. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/exceptions.py +0 -0
  21. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/execution.py +0 -0
  22. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/experience.py +0 -0
  23. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/openai_reflection.py +0 -0
  24. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/reflection_worker.py +0 -0
  25. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix/workflow.py +0 -0
  26. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix.egg-info/dependency_links.txt +0 -0
  27. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix.egg-info/entry_points.txt +0 -0
  28. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix.egg-info/requires.txt +0 -0
  29. {hebbrix-2.6.1 → hebbrix-2.6.2}/hebbrix.egg-info/top_level.txt +0 -0
  30. {hebbrix-2.6.1 → hebbrix-2.6.2}/setup.cfg +0 -0
  31. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_advanced_resources.py +0 -0
  32. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_advisor_integrity.py +0 -0
  33. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_evidence_loop_resource.py +0 -0
  34. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_evidence_safety_boundary.py +0 -0
  35. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_execution_permission.py +0 -0
  36. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_experience_request.py +0 -0
  37. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_experience_workflow.py +0 -0
  38. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_followup_helpers.py +0 -0
  39. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_memories_resource.py +0 -0
  40. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_openai_reflection.py +0 -0
  41. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_openapi_parity.py +0 -0
  42. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_outcome_advice_resource.py +0 -0
  43. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_procedural_resource.py +0 -0
  44. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_reflection_worker_cli.py +0 -0
  45. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_release_version.py +0 -0
  46. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_sync_client.py +0 -0
  47. {hebbrix-2.6.1 → hebbrix-2.6.2}/tests/test_workflow_route_contract.py +0 -0
@@ -1,5 +1,13 @@
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
+
3
11
  ## 2.6.1 — 2026-10-04 (advisory horizon helpers)
4
12
 
5
13
  - Carry optional remaining_decisions and max_pilot_decisions through evidence reads and the once-only advisor callback.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hebbrix
3
- Version: 2.6.1
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,7 +27,7 @@ License: MIT License
27
27
  SOFTWARE.
28
28
 
29
29
  Project-URL: Homepage, https://hebbrix.com
30
- Project-URL: Documentation, https://docs.hebbrix.com
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
@@ -65,54 +65,23 @@ Dynamic: license-file
65
65
 
66
66
  Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
67
67
 
68
- This branch is the **2.6.0 stable SDK**. The new policy configuration and
69
- advice helpers require backend schema `e5f6g7h8i868` or a compatible successor.
70
- A stable SDK does not qualify experimental learning or enable autonomous execution. ASK/REVIEW/ACT is advice;
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.0
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
- ProofLoop workflows; advanced temporal, working-memory, consolidation,
80
+ outcome-learning workflows; advanced temporal, working-memory, consolidation,
82
81
  memory-tool, and RL resources are currently async-only.
83
82
 
84
- The runtime requires `httpx>=0.25.0,<1`; incompatible 1.x prereleases are excluded.
85
- For the matching Round 5 backend, `setup_policy` accepts explicit `configuration`
86
- options for versioned change response and declared optional-field sharing, plus
87
- `value_objective={"success_value":10,"max_cost":20,"cost_unit":"USD"}`.
88
- Report both actual success and cost with `record_outcome`. Chat follow-up capture
89
- requires `features.learning: true` and an exact `outcome_followup.decision_id`;
90
- captured signals are provisional, not verified execution or autonomy evidence.
91
- These options require the matching runtime, not only the unchanged database schema.
92
-
93
83
  ## Quick start
94
84
 
95
- October 2 follow-up: `proofloop.setup_policy` atomically creates a new
96
- context/schema policy with explicitly declared low-risk exploration; existing
97
- policies are not migrated automatically. `learning_report` reads a bounded,
98
- scoped descriptive report, not proven uplift. `decide_with_advice` reads an
99
- evidence card, invokes the supplied advisor once and logs its actual choice and
100
- probabilities. `decide` accepts bounded `prior_action` / `prior_strength` for one
101
- server-selected decision; this is not outcome evidence. These new helpers and
102
- structured paraphrase matching require the matching October 2 outcome-followup
103
- backend, not merely its database schema; inspect `/v1/release` before use.
104
- Nothing here grants permission to execute. Learning performance and reliable
105
- model compliance with feedback are not established.
106
-
107
- Both clients expose `proofloop.register_context_schema`, `context_schema`,
108
- `configure_policy`, `policy_configuration`, `policy_advice` and `action_advice`.
109
- Enroll context before recording decisions. Configuration uses `expected_revision`
110
- for compare-and-swap; do not retry a conflict blindly. Exploration remains an
111
- explicit low-risk opt-in. `action_advice` takes the exact configured description,
112
- policy/action IDs and context, and maps `user_id` to the confidence endpoint's
113
- `end_user_id`. For the complete request shapes, see the
114
- [learning guide](https://www.hebbrix.com/docs/learning).
115
-
116
85
  ```python
117
86
  import asyncio
118
87
  from hebbrix import MemoryClient
@@ -135,6 +104,57 @@ async def main():
135
104
  asyncio.run(main())
136
105
  ```
137
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
+
138
158
  ## Durable readiness
139
159
 
140
160
  Memory writes return either a searchable completion or a durable `202` receipt.
@@ -215,7 +235,7 @@ The production API publishes exact build and artifact compatibility at
215
235
  [`GET /v1/release`](https://api.hebbrix.com/v1/release). The public OpenAPI is
216
236
  [`/openapi.json`](https://api.hebbrix.com/openapi.json).
217
237
 
218
- - [Documentation](https://docs.hebbrix.com)
238
+ - [Documentation](https://hebbrix.com/docs)
219
239
  - [API reference](https://api.hebbrix.com/docs)
220
240
  - [PyPI files](https://pypi.org/project/hebbrix/#files)
221
241
  - [Support](https://www.hebbrix.com/contact)
@@ -223,14 +243,25 @@ The production API publishes exact build and artifact compatibility at
223
243
  ## License
224
244
 
225
245
  MIT. See `LICENSE` in the distribution.
226
- ## Native experience workflow (prerelease)
246
+ ## Advanced evidence workflows
227
247
 
228
248
  The current source includes `client.experiences`, bounded reflection workers,
229
249
  separate lesson review/revision and explicit one-use execution admission. These
230
- methods require the matching new backend; the published 2.5.0 release does not
231
- include this extension. The candidate package supplies `hebbrix-reflect --help`.
250
+ methods require the server's published compatibility contract and separately
251
+ scoped credentials. The package supplies `hebbrix-reflect --help`.
232
252
  Importing it does not call a model, approve a lesson or execute a tool.
233
253
 
234
- See `docs/native-experience-operations.md` for role scopes,
254
+ See the [documentation](https://hebbrix.com/docs) for role scopes,
235
255
  uncertain-call recovery, exact-request binding and policy rollback. Do not treat a
236
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,54 +2,23 @@
2
2
 
3
3
  Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
4
4
 
5
- This branch is the **2.6.0 stable SDK**. The new policy configuration and
6
- advice helpers require backend schema `e5f6g7h8i868` or a compatible successor.
7
- A stable SDK does not qualify experimental learning or enable autonomous execution. ASK/REVIEW/ACT is advice;
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.0
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
- ProofLoop workflows; advanced temporal, working-memory, consolidation,
17
+ outcome-learning workflows; advanced temporal, working-memory, consolidation,
19
18
  memory-tool, and RL resources are currently async-only.
20
19
 
21
- The runtime requires `httpx>=0.25.0,<1`; incompatible 1.x prereleases are excluded.
22
- For the matching Round 5 backend, `setup_policy` accepts explicit `configuration`
23
- options for versioned change response and declared optional-field sharing, plus
24
- `value_objective={"success_value":10,"max_cost":20,"cost_unit":"USD"}`.
25
- Report both actual success and cost with `record_outcome`. Chat follow-up capture
26
- requires `features.learning: true` and an exact `outcome_followup.decision_id`;
27
- captured signals are provisional, not verified execution or autonomy evidence.
28
- These options require the matching runtime, not only the unchanged database schema.
29
-
30
20
  ## Quick start
31
21
 
32
- October 2 follow-up: `proofloop.setup_policy` atomically creates a new
33
- context/schema policy with explicitly declared low-risk exploration; existing
34
- policies are not migrated automatically. `learning_report` reads a bounded,
35
- scoped descriptive report, not proven uplift. `decide_with_advice` reads an
36
- evidence card, invokes the supplied advisor once and logs its actual choice and
37
- probabilities. `decide` accepts bounded `prior_action` / `prior_strength` for one
38
- server-selected decision; this is not outcome evidence. These new helpers and
39
- structured paraphrase matching require the matching October 2 outcome-followup
40
- backend, not merely its database schema; inspect `/v1/release` before use.
41
- Nothing here grants permission to execute. Learning performance and reliable
42
- model compliance with feedback are not established.
43
-
44
- Both clients expose `proofloop.register_context_schema`, `context_schema`,
45
- `configure_policy`, `policy_configuration`, `policy_advice` and `action_advice`.
46
- Enroll context before recording decisions. Configuration uses `expected_revision`
47
- for compare-and-swap; do not retry a conflict blindly. Exploration remains an
48
- explicit low-risk opt-in. `action_advice` takes the exact configured description,
49
- policy/action IDs and context, and maps `user_id` to the confidence endpoint's
50
- `end_user_id`. For the complete request shapes, see the
51
- [learning guide](https://www.hebbrix.com/docs/learning).
52
-
53
22
  ```python
54
23
  import asyncio
55
24
  from hebbrix import MemoryClient
@@ -72,6 +41,57 @@ async def main():
72
41
  asyncio.run(main())
73
42
  ```
74
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
+
75
95
  ## Durable readiness
76
96
 
77
97
  Memory writes return either a searchable completion or a durable `202` receipt.
@@ -152,7 +172,7 @@ The production API publishes exact build and artifact compatibility at
152
172
  [`GET /v1/release`](https://api.hebbrix.com/v1/release). The public OpenAPI is
153
173
  [`/openapi.json`](https://api.hebbrix.com/openapi.json).
154
174
 
155
- - [Documentation](https://docs.hebbrix.com)
175
+ - [Documentation](https://hebbrix.com/docs)
156
176
  - [API reference](https://api.hebbrix.com/docs)
157
177
  - [PyPI files](https://pypi.org/project/hebbrix/#files)
158
178
  - [Support](https://www.hebbrix.com/contact)
@@ -160,14 +180,25 @@ The production API publishes exact build and artifact compatibility at
160
180
  ## License
161
181
 
162
182
  MIT. See `LICENSE` in the distribution.
163
- ## Native experience workflow (prerelease)
183
+ ## Advanced evidence workflows
164
184
 
165
185
  The current source includes `client.experiences`, bounded reflection workers,
166
186
  separate lesson review/revision and explicit one-use execution admission. These
167
- methods require the matching new backend; the published 2.5.0 release does not
168
- include this extension. The candidate package supplies `hebbrix-reflect --help`.
187
+ methods require the server's published compatibility contract and separately
188
+ scoped credentials. The package supplies `hebbrix-reflect --help`.
169
189
  Importing it does not call a model, approve a lesson or execute a tool.
170
190
 
171
- See `docs/native-experience-operations.md` for role scopes,
191
+ See the [documentation](https://hebbrix.com/docs) for role scopes,
172
192
  uncertain-call recovery, exact-request binding and policy rollback. Do not treat a
173
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.1"
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,54 @@ 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
+
8
56
  def _validate_advisor_horizon(remaining_decisions, max_pilot_decisions):
9
57
  for field, value, maximum in (("remaining_decisions", remaining_decisions, 10000),
10
58
  ("max_pilot_decisions", max_pilot_decisions, 8)):
@@ -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.1",
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):