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.
Files changed (47) hide show
  1. {hebbrix-2.6.2 → hebbrix-2.6.3}/CHANGELOG.md +6 -0
  2. {hebbrix-2.6.2/hebbrix.egg-info → hebbrix-2.6.3}/PKG-INFO +8 -3
  3. {hebbrix-2.6.2 → hebbrix-2.6.3}/README.md +7 -2
  4. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/__init__.py +1 -1
  5. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/_advice.py +15 -1
  6. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/client.py +1 -1
  7. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/resources.py +9 -0
  8. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/sync_client.py +10 -1
  9. {hebbrix-2.6.2 → hebbrix-2.6.3/hebbrix.egg-info}/PKG-INFO +8 -3
  10. {hebbrix-2.6.2 → hebbrix-2.6.3}/pyproject.toml +1 -1
  11. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_advisor_integrity.py +30 -0
  12. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_customer_developer_experience.py +1 -1
  13. {hebbrix-2.6.2 → hebbrix-2.6.3}/LICENSE +0 -0
  14. {hebbrix-2.6.2 → hebbrix-2.6.3}/MANIFEST.in +0 -0
  15. {hebbrix-2.6.2 → hebbrix-2.6.3}/contracts/openapi-routes.json +0 -0
  16. {hebbrix-2.6.2 → hebbrix-2.6.3}/docs/native-experience-operations.md +0 -0
  17. {hebbrix-2.6.2 → hebbrix-2.6.3}/examples/native_reflection_worker.py +0 -0
  18. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/chat.py +0 -0
  19. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/exceptions.py +0 -0
  20. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/execution.py +0 -0
  21. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/experience.py +0 -0
  22. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/models.py +0 -0
  23. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/openai_reflection.py +0 -0
  24. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/reflection_worker.py +0 -0
  25. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix/workflow.py +0 -0
  26. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/SOURCES.txt +0 -0
  27. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/dependency_links.txt +0 -0
  28. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/entry_points.txt +0 -0
  29. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/requires.txt +0 -0
  30. {hebbrix-2.6.2 → hebbrix-2.6.3}/hebbrix.egg-info/top_level.txt +0 -0
  31. {hebbrix-2.6.2 → hebbrix-2.6.3}/setup.cfg +0 -0
  32. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_advanced_resources.py +0 -0
  33. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_evidence_loop_resource.py +0 -0
  34. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_evidence_safety_boundary.py +0 -0
  35. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_execution_permission.py +0 -0
  36. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_experience_request.py +0 -0
  37. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_experience_workflow.py +0 -0
  38. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_followup_helpers.py +0 -0
  39. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_memories_resource.py +0 -0
  40. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_openai_reflection.py +0 -0
  41. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_openapi_parity.py +0 -0
  42. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_outcome_advice_resource.py +0 -0
  43. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_procedural_resource.py +0 -0
  44. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_reflection_worker_cli.py +0 -0
  45. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_release_version.py +0 -0
  46. {hebbrix-2.6.2 → hebbrix-2.6.3}/tests/test_sync_client.py +0 -0
  47. {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.2
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.2**. Start with memory storage and search, or
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.2
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.2**. Start with memory storage and search, or
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.2
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.
@@ -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.2"
8
+ __version__ = "2.6.3"
9
9
  __author__ = "Hebbrix Team"
10
10
  __license__ = "MIT"
11
11
 
@@ -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 and features"
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
 
@@ -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.2",
96
+ "User-Agent": "hebbrix-python/2.6.3",
97
97
  }
98
98
 
99
99
  if self.api_key:
@@ -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.2",
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.2
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.2**. Start with memory storage and search, or
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.2
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.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hebbrix"
7
- version = "2.6.2"
7
+ version = "2.6.3"
8
8
  description = "Typed Python client for Hebbrix memory, retrieval, and outcome-learning APIs"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -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.2" in readme
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