[AAASM-4831] 🐛 (python): Harden langchain handler singleton + haystack positional-arg passthrough#278
Merged
Merged
Conversation
auto_inject_callback_handler kept the existing module-level singleton for any second call regardless of interceptor, so a differently-postured re-init without a prior shutdown() would silently reuse the stale handler. Return the existing handler only when the interceptor is identical; warn and replace otherwise. Defensive hardening — init_assembly blocks this path today (AAASM-4831). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
patched_invoke accepted **kwargs only, so a positional Tool.invoke(x) raised TypeError instead of being governed and forwarded. Accept *args and forward them to the wrapped invoke. Haystack's ToolInvoker calls invoke(**final_args) today, so this is defensive but matches the wrapped signature (AAASM-4831). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
Author
🤖 Claude Code — PR reviewScope (AAASM-4831, LOW): ✅ langchain callback handler warns+replaces on a differing-config re-init (was stale reuse); haystack
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Two non-exploitable hardening fixes (LOW cluster AAASM-4831) in the python-sdk framework adapters:
langchain (
adapters/langchain/runtime.py) —auto_inject_callback_handlerkept the module-level singleton for any second call regardless of the interceptor, so a differently-postured re-init without a priorshutdown()would silently reuse the stale handler. It now returns the existing handler only when the interceptor is identical (the matching-params re-init path, unchanged), and warns + clear-and-replaces on a mismatch.init_assemblyblocks this path today, so this is defensive hardening for future refactors.haystack (
adapters/haystack/patch.py) —patched_invokeaccepted**kwargsonly, so a positionalTool.invoke(x)raisedTypeError(crash, not a bypass). It now accepts*argsand forwards them to the wrappedinvoke, so a positional call is governed and forwarded. Haystack'sToolInvokercallsinvoke(**final_args)today, so this is defensive but matches the wrapped signature.Type of Change
Breaking Changes
Related Issues
Testing
Added regression tests: (1) re-injecting the langchain handler with a different interceptor warns (
RuntimeWarning) and replaces rather than silently keeping the stale one; existing idempotency test updated to use the same interceptor for the matching path. (2) haystackpatched_invokehandles a positional arg withoutTypeErrorand still governs (allow forwards, deny blocks the wrapped function).Validation:
pytest test/ -k "langchain or haystack"→ 183 passed, 3 skipped (haystack real-package tests, not installed);ruff check+ruff formatclean;mypy agent_assemblyclean on changed files.Checklist
🤖 Generated with Claude Code