hebbrix 2.6.2__tar.gz → 2.6.3__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.2 → hebbrix-2.6.3}/CHANGELOG.md +6 -0
- {hebbrix-2.6.2/hebbrix.egg-info → hebbrix-2.6.3}/PKG-INFO +8 -3
- {hebbrix-2.6.2 → hebbrix-2.6.3}/README.md +7 -2
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/__init__.py +1 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/_advice.py +15 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/client.py +1 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/resources.py +9 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/sync_client.py +10 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3/hebbrix.egg-info}/PKG-INFO +8 -3
- {hebbrix-2.6.2 → hebbrix-2.6.3}/pyproject.toml +1 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_advisor_integrity.py +30 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_customer_developer_experience.py +1 -1
- {hebbrix-2.6.2 → hebbrix-2.6.3}/LICENSE +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/MANIFEST.in +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/contracts/openapi-routes.json +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/docs/native-experience-operations.md +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/examples/native_reflection_worker.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/chat.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/exceptions.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/execution.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/experience.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/models.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/openai_reflection.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/reflection_worker.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/workflow.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/SOURCES.txt +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/dependency_links.txt +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/entry_points.txt +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/requires.txt +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/top_level.txt +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/setup.cfg +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_advanced_resources.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_evidence_loop_resource.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_evidence_safety_boundary.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_execution_permission.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_experience_request.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_experience_workflow.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_followup_helpers.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_memories_resource.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_openai_reflection.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_openapi_parity.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_outcome_advice_resource.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_procedural_resource.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_reflection_worker_cli.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_release_version.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_sync_client.py +0 -0
- {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_workflow_route_contract.py +0 -0
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.6.3 — 2026-10-14 (candidate memory_ids)
|
|
4
|
+
|
|
5
|
+
- Candidates may carry optional `memory_ids` (at most 50 ids of 1-255 characters) naming the exact memories that action applies; when the candidate becomes the decision's action, its outcome is credited to those memories.
|
|
6
|
+
- The advisor input snapshot (`decide_with_advice`) admits and validates `memory_ids` before any evidence read, callback or write; `proofloop.decide` documents the candidate shape.
|
|
7
|
+
- Requires the server release that credits outcomes only to memories bound to the action taken; a `proof_context` attests what was retrieved and no longer earns per-memory outcome credit by itself.
|
|
8
|
+
|
|
3
9
|
## 2.6.2 — 2026-10-06 (compact advice, batches and confirmation)
|
|
4
10
|
|
|
5
11
|
- Correct canonical documentation metadata and simplify the stable three-call guide.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hebbrix
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.3
|
|
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>
|
|
@@ -65,14 +65,14 @@ Dynamic: license-file
|
|
|
65
65
|
|
|
66
66
|
Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
|
|
67
67
|
|
|
68
|
-
The current stable package is **2.6.
|
|
68
|
+
The current stable package is **2.6.3**. Start with memory storage and search, or
|
|
69
69
|
the three-call outcome-learning workflow below. Advanced evidence and execution
|
|
70
70
|
permission transports are opt-in; installing the SDK never permits an action.
|
|
71
71
|
|
|
72
72
|
## Install
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
pip install hebbrix==2.6.
|
|
75
|
+
pip install hebbrix==2.6.3
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
Python 3.8+ is supported. `MemoryClient` is asynchronous. `SyncMemoryClient`
|
|
@@ -151,6 +151,11 @@ The canonical `gate` is `ASK`, `REVIEW`, `ACT`, or `BLOCK`. `BLOCK` dominates;
|
|
|
151
151
|
`ACT` is advice, not permission. Apply your own current authorization and human
|
|
152
152
|
approval policy before executing any tool. Do not infer permission from a score.
|
|
153
153
|
|
|
154
|
+
Version 2.6.3 lets each `proofloop.decide` candidate carry `memory_ids`: the exact
|
|
155
|
+
memories that action applies. When that candidate becomes the decision's action,
|
|
156
|
+
its outcome is credited to those memories; a `proof_context` attests what was
|
|
157
|
+
retrieved but never earns per-memory outcome credit by itself.
|
|
158
|
+
|
|
154
159
|
Version 2.6.2 adds compact advice, batch, and explicit confirmation helpers.
|
|
155
160
|
They require matching Round9 server routes. Compact views retain scope and safety
|
|
156
161
|
caveats; complete receipts remain on the server.
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
|
|
4
4
|
|
|
5
|
-
The current stable package is **2.6.
|
|
5
|
+
The current stable package is **2.6.3**. Start with memory storage and search, or
|
|
6
6
|
the three-call outcome-learning workflow below. Advanced evidence and execution
|
|
7
7
|
permission transports are opt-in; installing the SDK never permits an action.
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
pip install hebbrix==2.6.
|
|
12
|
+
pip install hebbrix==2.6.3
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Python 3.8+ is supported. `MemoryClient` is asynchronous. `SyncMemoryClient`
|
|
@@ -88,6 +88,11 @@ The canonical `gate` is `ASK`, `REVIEW`, `ACT`, or `BLOCK`. `BLOCK` dominates;
|
|
|
88
88
|
`ACT` is advice, not permission. Apply your own current authorization and human
|
|
89
89
|
approval policy before executing any tool. Do not infer permission from a score.
|
|
90
90
|
|
|
91
|
+
Version 2.6.3 lets each `proofloop.decide` candidate carry `memory_ids`: the exact
|
|
92
|
+
memories that action applies. When that candidate becomes the decision's action,
|
|
93
|
+
its outcome is credited to those memories; a `proof_context` attests what was
|
|
94
|
+
retrieved but never earns per-memory outcome credit by itself.
|
|
95
|
+
|
|
91
96
|
Version 2.6.2 adds compact advice, batch, and explicit confirmation helpers.
|
|
92
97
|
They require matching Round9 server routes. Compact views retain scope and safety
|
|
93
98
|
caveats; complete receipts remain on the server.
|
|
@@ -121,9 +121,11 @@ def _snapshot_advisor_inputs(candidates, context):
|
|
|
121
121
|
"action_key",
|
|
122
122
|
"description",
|
|
123
123
|
"features",
|
|
124
|
+
"memory_ids",
|
|
124
125
|
}:
|
|
125
126
|
raise ValueError(
|
|
126
|
-
"candidates must contain only action_key, description
|
|
127
|
+
"candidates must contain only action_key, description, features "
|
|
128
|
+
"and memory_ids"
|
|
127
129
|
)
|
|
128
130
|
key = candidate.get("action_key")
|
|
129
131
|
if (
|
|
@@ -145,6 +147,18 @@ def _snapshot_advisor_inputs(candidates, context):
|
|
|
145
147
|
)
|
|
146
148
|
if "features" in candidate and type(candidate["features"]) is not dict:
|
|
147
149
|
raise ValueError("candidate features must be a JSON object")
|
|
150
|
+
memory_ids = candidate.get("memory_ids")
|
|
151
|
+
if memory_ids is not None and (
|
|
152
|
+
type(memory_ids) is not list
|
|
153
|
+
or len(memory_ids) > 50
|
|
154
|
+
or any(
|
|
155
|
+
type(memory_id) is not str or not 1 <= len(memory_id) <= 255
|
|
156
|
+
for memory_id in memory_ids
|
|
157
|
+
)
|
|
158
|
+
):
|
|
159
|
+
raise ValueError(
|
|
160
|
+
"candidate memory_ids must be a list of at most 50 memory ids"
|
|
161
|
+
)
|
|
148
162
|
keys.append(key)
|
|
149
163
|
return candidates_copy, context_copy, keys
|
|
150
164
|
|
|
@@ -1170,6 +1170,15 @@ class ProofLoopResource(BaseResource):
|
|
|
1170
1170
|
idempotency_key: Optional[str] = None,
|
|
1171
1171
|
**kwargs,
|
|
1172
1172
|
) -> Dict[str, Any]:
|
|
1173
|
+
"""Log one decision among 1-50 candidate actions.
|
|
1174
|
+
|
|
1175
|
+
Each candidate is ``{"action_key": str, "description"?: str,
|
|
1176
|
+
"features"?: dict, "memory_ids"?: list[str]}``. ``memory_ids`` (at most
|
|
1177
|
+
50) names the exact memories the action applies, such as its runbook;
|
|
1178
|
+
when that candidate becomes the decision's action, its outcome is
|
|
1179
|
+
credited to those memories. A ``proof_context`` attests what was
|
|
1180
|
+
retrieved but never earns per-memory outcome credit by itself.
|
|
1181
|
+
"""
|
|
1173
1182
|
token = (
|
|
1174
1183
|
proof_context.get("token")
|
|
1175
1184
|
if isinstance(proof_context, dict)
|
|
@@ -649,6 +649,15 @@ class SyncProofLoopResource:
|
|
|
649
649
|
idempotency_key: Optional[str] = None,
|
|
650
650
|
**kwargs,
|
|
651
651
|
) -> Dict[str, Any]:
|
|
652
|
+
"""Log one decision among 1-50 candidate actions.
|
|
653
|
+
|
|
654
|
+
Each candidate is ``{"action_key": str, "description"?: str,
|
|
655
|
+
"features"?: dict, "memory_ids"?: list[str]}``. ``memory_ids`` (at most
|
|
656
|
+
50) names the exact memories the action applies, such as its runbook;
|
|
657
|
+
when that candidate becomes the decision's action, its outcome is
|
|
658
|
+
credited to those memories. A ``proof_context`` attests what was
|
|
659
|
+
retrieved but never earns per-memory outcome credit by itself.
|
|
660
|
+
"""
|
|
652
661
|
token = (
|
|
653
662
|
proof_context.get("token")
|
|
654
663
|
if isinstance(proof_context, dict)
|
|
@@ -1110,7 +1119,7 @@ class SyncMemoryClient:
|
|
|
1110
1119
|
self.source = source or os.getenv("HEBBRIX_SOURCE")
|
|
1111
1120
|
headers = {
|
|
1112
1121
|
"Content-Type": "application/json",
|
|
1113
|
-
"User-Agent": "hebbrix-python/2.6.
|
|
1122
|
+
"User-Agent": "hebbrix-python/2.6.3",
|
|
1114
1123
|
}
|
|
1115
1124
|
if api_key:
|
|
1116
1125
|
headers["Authorization"] = f"Bearer {api_key}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hebbrix
|
|
3
|
-
Version: 2.6.
|
|
3
|
+
Version: 2.6.3
|
|
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>
|
|
@@ -65,14 +65,14 @@ Dynamic: license-file
|
|
|
65
65
|
|
|
66
66
|
Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs.
|
|
67
67
|
|
|
68
|
-
The current stable package is **2.6.
|
|
68
|
+
The current stable package is **2.6.3**. Start with memory storage and search, or
|
|
69
69
|
the three-call outcome-learning workflow below. Advanced evidence and execution
|
|
70
70
|
permission transports are opt-in; installing the SDK never permits an action.
|
|
71
71
|
|
|
72
72
|
## Install
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
pip install hebbrix==2.6.
|
|
75
|
+
pip install hebbrix==2.6.3
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
Python 3.8+ is supported. `MemoryClient` is asynchronous. `SyncMemoryClient`
|
|
@@ -151,6 +151,11 @@ The canonical `gate` is `ASK`, `REVIEW`, `ACT`, or `BLOCK`. `BLOCK` dominates;
|
|
|
151
151
|
`ACT` is advice, not permission. Apply your own current authorization and human
|
|
152
152
|
approval policy before executing any tool. Do not infer permission from a score.
|
|
153
153
|
|
|
154
|
+
Version 2.6.3 lets each `proofloop.decide` candidate carry `memory_ids`: the exact
|
|
155
|
+
memories that action applies. When that candidate becomes the decision's action,
|
|
156
|
+
its outcome is credited to those memories; a `proof_context` attests what was
|
|
157
|
+
retrieved but never earns per-memory outcome credit by itself.
|
|
158
|
+
|
|
154
159
|
Version 2.6.2 adds compact advice, batch, and explicit confirmation helpers.
|
|
155
160
|
They require matching Round9 server routes. Compact views retain scope and safety
|
|
156
161
|
caveats; complete receipts remain on the server.
|
|
@@ -274,3 +274,33 @@ async def test_cyclic_json_is_refused_before_read(kind):
|
|
|
274
274
|
with pytest.raises(ValueError):
|
|
275
275
|
await invoke(kind, client, params, advisor)
|
|
276
276
|
client.get.assert_not_called()
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@pytest.mark.asyncio
|
|
280
|
+
@pytest.mark.parametrize("kind", ["sync", "async"])
|
|
281
|
+
async def test_candidate_memory_ids_reach_the_decision_unchanged(kind):
|
|
282
|
+
"""A candidate may bind the memories its action applies (outcome credit)."""
|
|
283
|
+
client = transport(kind)
|
|
284
|
+
params = inputs()
|
|
285
|
+
params["candidates"][1]["memory_ids"] = ["runbook-memory", "checklist-memory"]
|
|
286
|
+
await invoke(kind, client, params, Mock(return_value=choice()))
|
|
287
|
+
candidates = client.post.call_args.kwargs["json"]["candidates"]
|
|
288
|
+
assert candidates[1]["memory_ids"] == ["runbook-memory", "checklist-memory"]
|
|
289
|
+
assert "memory_ids" not in candidates[0]
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
@pytest.mark.asyncio
|
|
293
|
+
@pytest.mark.parametrize("kind", ["sync", "async"])
|
|
294
|
+
@pytest.mark.parametrize(
|
|
295
|
+
"memory_ids",
|
|
296
|
+
["runbook-memory", [""], ["x" * 256], [7], ["m"] * 51, {"id": "m"}],
|
|
297
|
+
)
|
|
298
|
+
async def test_invalid_candidate_memory_ids_fail_before_reads(kind, memory_ids):
|
|
299
|
+
client, advisor = transport(kind), Mock(return_value=choice())
|
|
300
|
+
params = inputs()
|
|
301
|
+
params["candidates"][0]["memory_ids"] = memory_ids
|
|
302
|
+
with pytest.raises(ValueError):
|
|
303
|
+
await invoke(kind, client, params, advisor)
|
|
304
|
+
client.get.assert_not_called()
|
|
305
|
+
client.post.assert_not_called()
|
|
306
|
+
advisor.assert_not_called()
|
|
@@ -162,6 +162,6 @@ def test_package_docs_metadata_uses_canonical_host():
|
|
|
162
162
|
assert 'Documentation = "https://hebbrix.com/docs"' in text
|
|
163
163
|
assert "docs.hebbrix.com" not in text
|
|
164
164
|
readme = (root / "README.md").read_text()
|
|
165
|
-
assert "pip install hebbrix==2.6.
|
|
165
|
+
assert "pip install hebbrix==2.6.3" in readme
|
|
166
166
|
assert "three calls" in readme
|
|
167
167
|
assert "schema `" not in readme
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|