-
Notifications
You must be signed in to change notification settings - Fork 150
feat(backends): LocalFileBinding implements verbs (PEFT/aLoRA path) + from_catalog() (Epic #929 Phase 2) #1454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
planetf1
merged 19 commits into
generative-computing:main
from
planetf1:worktree-issue-1141
Aug 17, 2026
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
04b5d0b
feat(backends): implement LocalFileBinding verbs and from_catalog()
planetf1 5b2c1a5
fix(backends): classify schema mismatches in adapter_scope; correct s…
planetf1 b771658
test(backends): correct the rationale in the hook-capture test helpers
planetf1 c0a364c
fix(backends): address review findings on release(), phase hooks and …
planetf1 9dda170
test(backends): make test_adapters a package, matching test/telemetry
planetf1 0c05582
docs(backends): fix RST cross-reference roles and stale-status docstr…
planetf1 9719f7d
fix(backends): fix leaked coroutine at the _run_async_in_thread helpe…
planetf1 46a789d
fix(backends): narrow event_loop_helper's close-on-failure catch to E…
planetf1 52e24f6
fix(backends): guarantee deactivate() runs after a successful activat…
planetf1 9b84a29
fix(backends): name the conflict when a LocalFileBinding blocks resol…
planetf1 afba145
test(backends): pin adapter_scope's new raise on shim-backed adapters
planetf1 ec3411f
fix(backends): close the internal wrapper coroutine on scheduling fai…
planetf1 d3dc793
fix(backends): make prepare() retryable after a load failure, enforce…
planetf1 6615ba5
fix(backends): lock PEFT load/unload in prepare()/release(); document…
planetf1 53843e8
fix(backends): isolate phase hook failures
planetf1 94b2b7c
fix(backends): preserve adapter lifecycle failures
planetf1 9df8503
fix(backends): guard binding lifecycle transitions
planetf1 39091e3
fix(backends): serialise binding lifecycle state
planetf1 0ceccc8
fix(backends): serialise binding lifecycle transitions
planetf1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # Copyright IBM Corp. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| # Copyright IBM Corp. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Shared helper for asserting on the adapter-function hooks (Epic #929). | ||
|
|
||
| Single home for the hook-capture idiom, so the patching contract below is stated | ||
| once. Not a `conftest.py` fixture: callers need to wrap a *specific* block inside | ||
| a test (the integration tests capture only the `adapter_scope` section, not the | ||
| whole test), which a fixture cannot express. | ||
|
|
||
| Assertions here are on **hooks, not spans**. `adapter_scope` fires hooks and never | ||
| opens a span — #1464 documents that rule, #1466 adds the spans from a plugin. | ||
| """ | ||
|
|
||
| import contextlib | ||
| from collections.abc import Iterator | ||
| from unittest.mock import MagicMock, patch | ||
|
|
||
| _TARGET = "mellea.backends.adapters.adapter" | ||
|
|
||
|
|
||
| @contextlib.contextmanager | ||
| def capture_adapter_hooks() -> Iterator[MagicMock]: | ||
| """Capture the hook payloads fired inside the block. | ||
|
|
||
| Patches three things, each for a distinct reason: | ||
|
|
||
| - **`has_plugins` pinned `True`.** It is already `True` under pytest — | ||
| `test/conftest.py`'s `auto_register_acceptance_sets` is `autouse`, | ||
| session-scoped, and registers a plugin for every `HookType` | ||
| (`test/plugins/_acceptance_sets.py`). Pinning it removes the dependency on | ||
| that ambient registration. | ||
| - **`invoke_hook` replaced with `new_callable=MagicMock`.** Load-bearing: | ||
| `invoke_hook` is an `async def`, so a bare `patch()` auto-creates an | ||
| `AsyncMock`. Calling an `AsyncMock` returns a coroutine, and if a | ||
| `side_effect` returns a coroutine of its own, *that* inner coroutine becomes | ||
| the outer one's result and is never awaited — surfacing as | ||
| `PytestUnraisableExceptionWarning: coroutine ... was never awaited`. Note | ||
| `-W error::RuntimeWarning` does **not** catch it; use | ||
| `-W error::pytest.PytestUnraisableExceptionWarning`. Forcing a sync | ||
| `MagicMock` means no coroutine exists to leak. | ||
| - **`_run_async_in_thread` patched out.** Real dispatch works fine; it is | ||
| simply not needed to read the payloads, and skipping it keeps these tests | ||
| off the shared event loop. | ||
|
|
||
| Yields: | ||
| The `invoke_hook` mock. Use `hook_payloads()` to read what it recorded. | ||
| """ | ||
| with ( | ||
| patch(f"{_TARGET}.has_plugins", return_value=True), | ||
| patch(f"{_TARGET}.invoke_hook", new_callable=MagicMock) as mock_invoke, | ||
| patch(f"{_TARGET}._run_async_in_thread"), | ||
| ): | ||
| yield mock_invoke | ||
|
|
||
|
|
||
| def hook_payloads(mock_invoke: MagicMock) -> list: | ||
| """Returns the payload argument of every recorded `invoke_hook` call, in order. | ||
|
|
||
| Args: | ||
| mock_invoke: The mock yielded by `capture_adapter_hooks`. | ||
|
|
||
| Returns: | ||
| Each call's payload, ordered as fired. | ||
| """ | ||
| return [call.args[1] for call in mock_invoke.call_args_list] | ||
|
|
||
|
|
||
| def phase_payloads(mock_invoke: MagicMock) -> list: | ||
| """Returns only the phase-complete payloads. | ||
|
|
||
| Args: | ||
| mock_invoke: The mock yielded by `capture_adapter_hooks`. | ||
|
|
||
| Returns: | ||
| The recorded `AdapterFunctionPhaseCompletePayload`s, ordered as fired. | ||
| """ | ||
| return [p for p in hook_payloads(mock_invoke) if hasattr(p, "phase")] | ||
|
|
||
|
|
||
| def invocation_payloads(mock_invoke: MagicMock) -> list: | ||
| """Returns only the invocation-complete payloads. | ||
|
|
||
| Args: | ||
| mock_invoke: The mock yielded by `capture_adapter_hooks`. | ||
|
|
||
| Returns: | ||
| The recorded `AdapterFunctionInvocationCompletePayload`s, ordered as fired. | ||
| """ | ||
| return [p for p in hook_payloads(mock_invoke) if hasattr(p, "outcome")] |
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.