feat(core): add a resource registry beside the tool catalog [TOO-1932] - #918
Open
EricGustin wants to merge 1 commit into
Open
Conversation
This was referenced Aug 25, 2026
Codecov Report❌ Patch coverage is
🚀 New features to boost your workflow:
|
EricGustin
force-pushed
the
ericgustin/too-1931-mcp-resource-models-to-arcade-core
branch
from
August 26, 2026 06:56
b5642b7 to
1d296c5
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 06:56
28189ab to
155d9b0
Compare
EricGustin
commented
Aug 26, 2026
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 18:20
155d9b0 to
32e510b
Compare
11 tasks
EricGustin
force-pushed
the
ericgustin/too-1931-resource-schema-to-arcade-core
branch
from
August 26, 2026 20:32
1d296c5 to
d3eb3a2
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 20:32
32e510b to
946771a
Compare
EricGustin
marked this pull request as ready for review
August 26, 2026 21:19
Greptile SummaryThe PR adds a static URI-to-resource registry to
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| libs/arcade-core/arcade_core/resources.py | Adds resource storage, lookup, deterministic pagination, typed text/blob contents, cursor validation, and positive page-size enforcement; the previous pagination defect is fixed. |
| libs/arcade-core/arcade_core/catalog.py | Attaches a separately instantiated resource registry to each ToolCatalog through a Pydantic private attribute. |
| libs/tests/core/test_resource_registry.py | Covers resource types, cursor behavior, ordering, replacement, catalog isolation, missing resources, and page-size validation. |
| libs/arcade-core/pyproject.toml | Applies the required minor version increase for the new core-library functionality. |
Reviews (3): Last reviewed commit: "feat(core): add a resource registry besi..." | Re-trigger Greptile
EricGustin
force-pushed
the
ericgustin/too-1931-resource-schema-to-arcade-core
branch
from
August 26, 2026 22:08
d3eb3a2 to
77fee3a
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 26, 2026 22:08
946771a to
590e7f4
Compare
EricGustin
force-pushed
the
ericgustin/too-1931-resource-schema-to-arcade-core
branch
from
August 27, 2026 00:15
77fee3a to
b8871e0
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 27, 2026 00:15
590e7f4 to
ccc7675
Compare
A URI-to-resource registry in arcade-core, with its own type and its own file. Resources on this path are static, so contents resolve once at registration and are held: the endpoints that read this registry stay a serialization shim with nothing executing on the request path. The registry hangs off ToolCatalog because that is the only object handed to the worker (worker.catalog = catalog). Anything not on the catalog needs new plumbing through the server factory to get there. It is a private attribute with a default_factory rather than a bare mutable class default, so two catalogs never share one registry. Text and binary are kept apart by type rather than by emptiness, so a zero-length document and a zero-length blob stay distinguishable to the caller. Listing is ordered by URI so a cursor keeps its meaning when the next page is served by a different process. A worker can run as several processes behind one address, and none of them shares insertion order. add keeps the URI index sorted so list is a slice. A worker registers its resources once at startup and lists them on every request, so the ordering cost belongs on the write.
EricGustin
force-pushed
the
ericgustin/too-1931-resource-schema-to-arcade-core
branch
from
August 27, 2026 15:28
b8871e0 to
5944cbf
Compare
EricGustin
force-pushed
the
ericgustin/too-1932-resource-registry
branch
from
August 27, 2026 15:35
ccc7675 to
0c3d732
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
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.
Summary
Adds a URI-to-resource registry to
arcade-core, so a worker has somewhere to keep the resources a toolkit ships. Its own type, its own file.Resources on this path are static. Contents resolve once when a toolkit registers and are held from then on, so nothing executes while a request is in flight and the endpoints that read this registry stay a thin serialization layer.
Part 2 of 6. Stacked on #923.
Resolves: https://linear.app/arcadedev/issue/TOO-1932
Design decisions
The registry hangs off
ToolCatalog. That is the one object the server factory hands to the worker (worker.catalog = catalog), so anything living elsewhere needs new plumbing to reach it. The registry is still a separate type in a separate file; the catalog just carries it. It is aPrivateAttrwith adefault_factory, so two catalogs can never end up sharing one registry. There is a test for that, because the bare-mutable-class-default version of this bug is easy to write and hard to see.Listing is ordered by URI, and the order is kept on the write. A worker can run as several processes behind one address, and a cursor issued by one process has to mean the same thing when the next page lands on a different one. Insertion order gives you no such guarantee.
addkeeps a URI index sorted withbisect.insortandlistslices it, so the read isO(page_size)rather than sorting the whole set each time. A worker registers once at startup and lists on every request, so the ordering cost belongs on the write. Re-registering a URI replaces in place without inserting a second time.page_sizevalidates on assignment rather than only in__init__, because it is a public attribute callers set directly. A non-positive value makes cursor paging non-terminating: zero hands back an empty page and the same cursor forever, and a negative one walks the offset backwards into a cursor this registry then rejects as malformed.Text and blob stay separate types. Keeping them apart by type, instead of by which field happens to be empty, means a zero-length document and a zero-length blob remain distinguishable all the way out to the caller.
Test plan
libs/tests/core/test_resource_registry.py: the text/blob split, cursor round-tripping, rejection of a cursor this registry did not issue, per-catalog isolation, that replacing a URI leaves exactly one entry in the ordered index, and that a non-positivepage_sizeis refused at construction and at assignmentuv run pytest libs/tests: 3807 passed, 1 skippeduv run mypy .clean in each of the four librariesruff checkandruff format --checkclean on every touched fileAuthor checklist
Before moving this PR from Draft to Ready for Review:
make checkandmake testare green locally; CI is expected to passNote
Low Risk
Adds new in-memory registry APIs and catalog wiring only; no request-path execution or changes to auth or tool execution.
Overview
Introduces a new
ResourceRegistryinarcade_core.resourcesso workers can hold static toolkit resources (for upcomingresources/*serving) with contents resolved once at registration, not on each request.The registry maps URIs to
RegisteredResourceentries, wrappingstrasTextResourceContentsandbytesas base64BlobResourceContentsso empty text and empty blobs stay distinct.addreplaces by URI without duplicating the sorted URI index;listpages with opaque offset cursors and URI sort order (maintained viainsorton write) so pagination stays consistent across multi-process workers.page_sizeis validated on assignment; malformed cursors raiseInvalidCursorError.ToolCatalognow exposes a per-instance registry viaPrivateAttr(default_factory=ResourceRegistry)and aresourcesproperty—the catalog is the delivery path to the worker without merging resource types into tool catalog logic.arcade-corebumps to 4.13.0;test_resource_registry.pyadds coverage for registration, paging, cursors, and catalog isolation.Reviewed by Cursor Bugbot for commit 0c3d732. Bugbot is set up for automated code reviews on this repo. Configure here.