feedback-manager 0.1.0__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 (57) hide show
  1. feedback_manager-0.1.0/PKG-INFO +380 -0
  2. feedback_manager-0.1.0/README.md +352 -0
  3. feedback_manager-0.1.0/pyproject.toml +120 -0
  4. feedback_manager-0.1.0/pyproject.toml.orig +103 -0
  5. feedback_manager-0.1.0/src/feedback_manager/__init__.py +75 -0
  6. feedback_manager-0.1.0/src/feedback_manager/_logging.py +31 -0
  7. feedback_manager-0.1.0/src/feedback_manager/api/__init__.py +7 -0
  8. feedback_manager-0.1.0/src/feedback_manager/api/manager.py +339 -0
  9. feedback_manager-0.1.0/src/feedback_manager/api/queries.py +11 -0
  10. feedback_manager-0.1.0/src/feedback_manager/api/subscription.py +27 -0
  11. feedback_manager-0.1.0/src/feedback_manager/contracts/__init__.py +32 -0
  12. feedback_manager-0.1.0/src/feedback_manager/contracts/correlator.py +20 -0
  13. feedback_manager-0.1.0/src/feedback_manager/contracts/handler.py +46 -0
  14. feedback_manager-0.1.0/src/feedback_manager/contracts/policy.py +33 -0
  15. feedback_manager-0.1.0/src/feedback_manager/contracts/router.py +27 -0
  16. feedback_manager-0.1.0/src/feedback_manager/contracts/serializer.py +35 -0
  17. feedback_manager-0.1.0/src/feedback_manager/contracts/store.py +106 -0
  18. feedback_manager-0.1.0/src/feedback_manager/contracts/subscriber.py +22 -0
  19. feedback_manager-0.1.0/src/feedback_manager/core/__init__.py +32 -0
  20. feedback_manager-0.1.0/src/feedback_manager/core/_open_value.py +37 -0
  21. feedback_manager-0.1.0/src/feedback_manager/core/categories.py +55 -0
  22. feedback_manager-0.1.0/src/feedback_manager/core/context.py +60 -0
  23. feedback_manager-0.1.0/src/feedback_manager/core/events.py +71 -0
  24. feedback_manager-0.1.0/src/feedback_manager/core/lifecycle.py +114 -0
  25. feedback_manager-0.1.0/src/feedback_manager/core/provenance.py +34 -0
  26. feedback_manager-0.1.0/src/feedback_manager/core/sources.py +42 -0
  27. feedback_manager-0.1.0/src/feedback_manager/core/status.py +36 -0
  28. feedback_manager-0.1.0/src/feedback_manager/core/targets.py +65 -0
  29. feedback_manager-0.1.0/src/feedback_manager/correlation/__init__.py +5 -0
  30. feedback_manager-0.1.0/src/feedback_manager/correlation/correlator.py +41 -0
  31. feedback_manager-0.1.0/src/feedback_manager/errors/__init__.py +27 -0
  32. feedback_manager-0.1.0/src/feedback_manager/errors/exceptions.py +99 -0
  33. feedback_manager-0.1.0/src/feedback_manager/handlers/__init__.py +5 -0
  34. feedback_manager-0.1.0/src/feedback_manager/handlers/audit.py +41 -0
  35. feedback_manager-0.1.0/src/feedback_manager/integrations/__init__.py +5 -0
  36. feedback_manager-0.1.0/src/feedback_manager/integrations/langchain/__init__.py +6 -0
  37. feedback_manager-0.1.0/src/feedback_manager/integrations/langchain/adapter.py +24 -0
  38. feedback_manager-0.1.0/src/feedback_manager/integrations/langchain/callbacks.py +118 -0
  39. feedback_manager-0.1.0/src/feedback_manager/integrations/langchain/tools.py +48 -0
  40. feedback_manager-0.1.0/src/feedback_manager/integrations/langgraph/__init__.py +7 -0
  41. feedback_manager-0.1.0/src/feedback_manager/integrations/langgraph/adapter.py +54 -0
  42. feedback_manager-0.1.0/src/feedback_manager/integrations/langgraph/interrupt.py +93 -0
  43. feedback_manager-0.1.0/src/feedback_manager/integrations/langgraph/streaming.py +32 -0
  44. feedback_manager-0.1.0/src/feedback_manager/integrations/xai/__init__.py +5 -0
  45. feedback_manager-0.1.0/src/feedback_manager/integrations/xai/adapter.py +96 -0
  46. feedback_manager-0.1.0/src/feedback_manager/observability/__init__.py +29 -0
  47. feedback_manager-0.1.0/src/feedback_manager/observability/hooks.py +78 -0
  48. feedback_manager-0.1.0/src/feedback_manager/policies/__init__.py +7 -0
  49. feedback_manager-0.1.0/src/feedback_manager/policies/delivery.py +23 -0
  50. feedback_manager-0.1.0/src/feedback_manager/policies/failure.py +96 -0
  51. feedback_manager-0.1.0/src/feedback_manager/policies/retention.py +35 -0
  52. feedback_manager-0.1.0/src/feedback_manager/py.typed +0 -0
  53. feedback_manager-0.1.0/src/feedback_manager/routing/__init__.py +19 -0
  54. feedback_manager-0.1.0/src/feedback_manager/routing/default_router.py +50 -0
  55. feedback_manager-0.1.0/src/feedback_manager/routing/rules.py +51 -0
  56. feedback_manager-0.1.0/src/feedback_manager/storage/__init__.py +5 -0
  57. feedback_manager-0.1.0/src/feedback_manager/storage/memory.py +94 -0
@@ -0,0 +1,380 @@
1
+ Metadata-Version: 2.4
2
+ Name: feedback-manager
3
+ Version: 0.1.0
4
+ Summary: Production-grade feedback infrastructure for LangChain/LangGraph applications: capture, correlate, persist, route, and resolve feedback as a first-class domain concern.
5
+ Keywords: langchain,langgraph,feedback,hitl,human-in-the-loop,provenance
6
+ Author: S MUNI HARISH
7
+ Author-email: S MUNI HARISH <samamuniharish@gmail.com>
8
+ License-Expression: Apache-2.0
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Typing :: Typed
16
+ Requires-Dist: langchain-core>=1.6,<2
17
+ Requires-Dist: langgraph>=1.2.11,<1.3
18
+ Requires-Dist: langgraph-xai>=0.1.0,<0.2
19
+ Requires-Dist: pydantic>=2.12,<3
20
+ Requires-Dist: structlog>=25.1,<27
21
+ Requires-Python: >=3.12, <3.15
22
+ Project-URL: Homepage, https://github.com/samamuniharish/feedback-manager
23
+ Project-URL: Documentation, https://feedback-manager.readthedocs.io
24
+ Project-URL: Repository, https://github.com/samamuniharish/feedback-manager
25
+ Project-URL: Issues, https://github.com/samamuniharish/feedback-manager/issues
26
+ Project-URL: Changelog, https://github.com/samamuniharish/feedback-manager/blob/main/CHANGELOG.md
27
+ Description-Content-Type: text/markdown
28
+
29
+ # feedback-manager
30
+
31
+ Production-grade feedback infrastructure for LangChain and LangGraph applications.
32
+
33
+ `feedback-manager` treats feedback as a first-class domain concern: capture it, correlate it to execution context, persist it, route it to handlers, and move it through an explicit lifecycle.
34
+
35
+ It is a **library**, not an agent framework or runtime.
36
+
37
+ ## What it solves
38
+
39
+ Agent applications often need to handle feedback from many places:
40
+
41
+ - human corrections on generated answers
42
+ - approval or rejection decisions in human-in-the-loop flows
43
+ - tool failures and timeouts
44
+ - evaluator scores and critiques
45
+ - generation interruptions or partial results
46
+ - provenance-linked review or audit events
47
+
48
+ Without a dedicated feedback model, that data usually ends up fragmented across logs, UIs, tickets, and one-off tables.
49
+
50
+ `feedback-manager` gives you:
51
+
52
+ - a typed feedback event model
53
+ - correlation to runs, threads, checkpoints, nodes, tools, and generations
54
+ - explicit lifecycle management
55
+ - pluggable storage, routing, handlers, policies, and observability
56
+ - framework helpers for LangChain callbacks and LangGraph human-in-the-loop
57
+ flows
58
+ - provenance correlation backed exclusively by `langgraph-xai`
59
+
60
+ ## What it does not do
61
+
62
+ `feedback-manager` does **not**:
63
+
64
+ - execute agents
65
+ - orchestrate graphs
66
+ - replace LangGraph interrupts, checkpoints, or streaming
67
+ - implement evaluators or LLM-as-judge systems
68
+ - perform self-improvement or policy learning
69
+ - own your application's business workflow
70
+
71
+ LangChain, LangGraph, `langgraph-xai`, and your application code keep those responsibilities.
72
+
73
+ ## Installation
74
+
75
+ Requirements:
76
+
77
+ - Python `>=3.12,<3.15`
78
+
79
+ Install the package:
80
+
81
+ ```powershell
82
+ pip install .
83
+ ```
84
+
85
+ or for local development:
86
+
87
+ ```powershell
88
+ uv sync --all-groups
89
+ ```
90
+
91
+ Runtime dependencies are mandatory, not optional extras:
92
+
93
+ - `langchain-core>=1.6,<2`
94
+ - `langgraph>=1.2.11,<1.3`
95
+ - `langgraph-xai>=0.1.0,<0.2`
96
+ - `pydantic>=2.12,<3`
97
+
98
+ ## How it fits
99
+
100
+ Applications interact with a small public surface:
101
+
102
+ - create and query feedback through `FeedbackManager`
103
+ - describe feedback using `FeedbackEvent`, source, category, target, and
104
+ execution-context types
105
+ - replace documented persistence, routing, handler, policy, and
106
+ observability contracts when production infrastructure requires it
107
+ - pass `XAIRuntime` directly to `FeedbackManager` for provenance
108
+ - opt into the documented LangChain or LangGraph helpers where useful
109
+
110
+ The happy-path lifecycle is:
111
+
112
+ ```text
113
+ RECEIVED -> ACKNOWLEDGED -> HANDLED -> RESOLVED
114
+ ```
115
+
116
+ `resolve()` requires the event to already be `HANDLED`.
117
+
118
+ ## Core concepts
119
+
120
+ ### Source
121
+
122
+ Who or what produced the feedback:
123
+
124
+ - `human`
125
+ - `tool`
126
+ - `generation`
127
+ - `evaluator`
128
+ - `system`
129
+ - and custom open values
130
+
131
+ ### Category
132
+
133
+ What kind of feedback it is:
134
+
135
+ - `correction`
136
+ - `approval`
137
+ - `rejection`
138
+ - `timeout`
139
+ - `quality`
140
+ - `interruption`
141
+ - and custom open values
142
+
143
+ ### Target
144
+
145
+ What the feedback is about:
146
+
147
+ - graph
148
+ - run
149
+ - node
150
+ - tool call
151
+ - generation
152
+ - message
153
+ - state
154
+
155
+ ### Correlation
156
+
157
+ Feedback can be linked to:
158
+
159
+ - `run_id`
160
+ - `thread_id`
161
+ - `checkpoint_id`
162
+ - `node_id`
163
+ - `tool_call_id`
164
+ - `generation_id`
165
+
166
+ ### Provenance
167
+
168
+ When used with `langgraph-xai`, feedback can carry a `FeedbackProvenanceReference` resolved from an active run or from a provenance store by `run_id`.
169
+
170
+ ## Quick start
171
+
172
+ ```python
173
+ import asyncio
174
+
175
+ from feedback_manager import (
176
+ ExecutionContext,
177
+ FeedbackCategory,
178
+ FeedbackManager,
179
+ FeedbackSource,
180
+ FeedbackTarget,
181
+ FeedbackTargetType,
182
+ )
183
+
184
+
185
+ async def main() -> None:
186
+ manager = FeedbackManager()
187
+
188
+ feedback = await manager.submit(
189
+ source=FeedbackSource.HUMAN,
190
+ category=FeedbackCategory.CORRECTION,
191
+ target=FeedbackTarget(type=FeedbackTargetType.GENERATION, id="gen-42"),
192
+ payload={
193
+ "original_text": "The capital of Australia is Sydney.",
194
+ "corrected_text": "The capital of Australia is Canberra.",
195
+ },
196
+ execution_context=ExecutionContext(generation_id="gen-42"),
197
+ )
198
+
199
+ await manager.acknowledge(feedback.feedback_id)
200
+ await manager.mark_handled(feedback.feedback_id)
201
+ resolved = await manager.resolve(
202
+ feedback.feedback_id,
203
+ resolution={"applied": True, "channel": "manual_review"},
204
+ )
205
+
206
+ print(resolved.status)
207
+ print(resolved.metadata["resolution"])
208
+
209
+
210
+ asyncio.run(main())
211
+ ```
212
+
213
+ ## LangChain example
214
+
215
+ `FeedbackCallbackHandler` turns real LangChain callback errors into feedback:
216
+
217
+ ```python
218
+ import asyncio
219
+
220
+ from langchain_core.tools import tool
221
+
222
+ from feedback_manager import FeedbackManager
223
+ from feedback_manager.integrations.langchain import FeedbackCallbackHandler
224
+
225
+
226
+ @tool
227
+ async def fetch_weather(city: str) -> str:
228
+ raise TimeoutError(f"weather service timed out looking up {city!r}")
229
+
230
+
231
+ async def main() -> None:
232
+ manager = FeedbackManager()
233
+ handler = FeedbackCallbackHandler(manager)
234
+
235
+ try:
236
+ await fetch_weather.ainvoke({"city": "Canberra"}, config={"callbacks": [handler]})
237
+ except TimeoutError:
238
+ pass
239
+
240
+ events = await manager.list()
241
+ print(events[0].source, events[0].category, events[0].target.type)
242
+
243
+
244
+ asyncio.run(main())
245
+ ```
246
+
247
+ ## LangGraph example
248
+
249
+ Extract execution identifiers from a `RunnableConfig`:
250
+
251
+ ```python
252
+ from feedback_manager.integrations.langgraph import execution_context_from_config
253
+
254
+ config = {
255
+ "configurable": {"thread_id": "thread-1", "checkpoint_id": "cp-1"},
256
+ "metadata": {"xai_application_id": "support-bot"},
257
+ }
258
+
259
+ context = execution_context_from_config(config, node_id="answer_node")
260
+ print(context.thread_id, context.checkpoint_id, context.node_id)
261
+ ```
262
+
263
+ ## HITL example
264
+
265
+ Use native LangGraph interrupts and record the approval request with `HumanInTheLoopBridge`:
266
+
267
+ ```python
268
+ import asyncio
269
+
270
+ from feedback_manager import FeedbackManager, FeedbackTarget, FeedbackTargetType
271
+ from feedback_manager.integrations.langgraph import HumanInTheLoopBridge
272
+
273
+
274
+ async def main() -> None:
275
+ manager = FeedbackManager()
276
+ bridge = HumanInTheLoopBridge(manager)
277
+
278
+ feedback = await bridge.request(
279
+ target=FeedbackTarget(type=FeedbackTargetType.GRAPH, id="approval-flow"),
280
+ prompt={"question": "Approve sending this email?"},
281
+ )
282
+
283
+ resolved = await bridge.resolve(feedback.feedback_id, response="approved", approved=True)
284
+ resume = bridge.resume_command("approved")
285
+ print(resolved.status, resume)
286
+
287
+
288
+ asyncio.run(main())
289
+ ```
290
+
291
+ This complements LangGraph's runtime instead of replacing it.
292
+
293
+ ## Provenance example
294
+
295
+ Attach provenance from `langgraph-xai` by passing the runtime directly --
296
+ `FeedbackManager` wires up the provenance adapter automatically:
297
+
298
+ ```python
299
+ from langgraph_xai import XAIRuntime
300
+
301
+ from feedback_manager import FeedbackManager
302
+
303
+ runtime = XAIRuntime(
304
+ application_id="support-bot",
305
+ tenant_id="acme-corp",
306
+ graph_id="qa-graph",
307
+ )
308
+ manager = FeedbackManager(xai_runtime=runtime)
309
+ ```
310
+
311
+ When `manager.submit(...)` runs inside an instrumented graph node, the adapter can resolve provenance from `runtime.current_run`.
312
+
313
+ ## Extension example
314
+
315
+ ### Custom source/category values
316
+
317
+ ```python
318
+ from feedback_manager import FeedbackCategory, FeedbackSource
319
+
320
+ source = FeedbackSource("mcp_server")
321
+ category = FeedbackCategory("business_policy_violation")
322
+ ```
323
+
324
+ ### Custom store
325
+
326
+ ```python
327
+ from collections.abc import Sequence
328
+ from uuid import UUID
329
+
330
+ from feedback_manager.contracts import FeedbackQuery, FeedbackStore
331
+ from feedback_manager import FeedbackEvent, FeedbackStatus
332
+
333
+
334
+ class MyStore(FeedbackStore):
335
+ async def create(self, feedback: FeedbackEvent) -> FeedbackEvent: ...
336
+ async def get(self, feedback_id: UUID) -> FeedbackEvent | None: ...
337
+ async def update(self, feedback: FeedbackEvent) -> FeedbackEvent: ...
338
+ async def transition(self, feedback_id: UUID, status: FeedbackStatus) -> FeedbackEvent: ...
339
+ async def query(self, query: FeedbackQuery) -> Sequence[FeedbackEvent]: ...
340
+ async def list(self) -> Sequence[FeedbackEvent]: ...
341
+ ```
342
+
343
+ ### Custom handler
344
+
345
+ ```python
346
+ from feedback_manager.contracts import FeedbackContext, FeedbackHandler, FeedbackHandlerResult
347
+ from feedback_manager import FeedbackEvent
348
+
349
+
350
+ class HumanReviewHandler(FeedbackHandler):
351
+ async def handle(
352
+ self, feedback: FeedbackEvent, context: FeedbackContext
353
+ ) -> FeedbackHandlerResult:
354
+ return FeedbackHandlerResult(handled=True, detail="queued for review")
355
+ ```
356
+
357
+ ## Documentation
358
+
359
+ The full documentation site lives under `docs/` and includes:
360
+
361
+ - architecture guides
362
+ - ADRs
363
+ - getting-started guides
364
+ - concept references
365
+ - integration guides
366
+ - API reference
367
+ - advanced extension guides
368
+ - reliability, security, testing, and FAQ pages
369
+
370
+ Published documentation URL (project metadata): <https://feedback-manager.readthedocs.io>
371
+
372
+ ## Contributing
373
+
374
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for local development setup, running
375
+ the test suite/coverage, linting, type-checking, and building the docs site.
376
+
377
+ ## Author and license
378
+
379
+ - Author: **S MUNI HARISH**
380
+ - License: **Apache License 2.0**