Repository navigation
catalog-tools: create and prioritise catalog offerings (CL-7468) - #654
Merged
Merged
Conversation
Covers the happy path, a 403 from the hub, and an unknown canonical name/provider name for create_offering, set_offering_priority, and disable_offering ahead of the implementation.
…fering Lets an agent manage the tenant's own inference catalog offerings through the existing tenant-admin catalog routes, resolving a model's canonical name and a provider's name against this tenant's own catalog before writing, and refusing rather than guessing when either name isn't found. create_offering and disable_offering require approval; set_offering_priority only reorders an offering already live. Seeds the model/model-provider/model-offering read, create, and manage grants these routes require.
A workflow child authenticates with its sidecar bearer token and run address, never a browser session, so it cannot reach the tenant-admin catalog routes @intx/hub-api mounts for the settings UI. This adds a mirror at /api/workflow-catalog-admin, gated by the same grant store and pushing the same source-update refresh on every offering write.
create_offering, set_offering_priority, and disable_offering called the tenant-session catalog routes directly, so a workflow run's sidecar bearer and run address 401ed against them. Point the admin client at the new /api/workflow-catalog-admin mount instead, mounted in apps/hub beside its own read-only inference-catalog counterpart, and drop the tenantId the client no longer needs to carry now that the hub resolves it from the same credential.
The pin was still at 0.0.2 after the package's version moved to 0.0.3, and this change moves it again to 0.0.4 for the new workflow-run-authenticated routes.
The offering-management tools' README still described them as writing through the tenant-admin catalog routes directly; point it at the package's own workflow-run-authenticated mirror instead.
Resolves conflicts with the newly-merged access-tools work by keeping both routes mounted and both grant sets. The catalog-offering grants (model:*/model-provider:*/model-offering:* read/create/manage) now land on Myra's own run principal alongside the access-tools grants, following the same CL-7467 pattern, instead of tenant-wide via SEED_GRANTS.
…into cl-7468-fix2
pack.test.ts already re-imports every @corbits tool package's packed tarball and checks it exports at least one tool factory, but a bundle dropped from catalog-tools' index.ts re-exports would still leave that count above zero. Assert both catalogTools and catalogOfferingTools resolve by id from the actual packed tool.mjs the sidecar loads.
or() is called with two always-defined branches in both the /models and /providers cursor conditions, so it never actually returns undefined; the `?? eq(x.id, x.id)` fallback was a no-op that always matched. Replace it with `?? sql\`false\``, the same fallback vendor/intx/hub-api's own cursorCondition uses for the identical never-undefined case.
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
@corbits/catalog-tools:create_offering,set_offering_priority, anddisable_offering, letting an agent manage the tenant's own inference-catalog offerings.@corbits/catalog-tools' own workflow-run-authenticated mirror of the tenant-admin catalog routes (packages/catalog-tools/src/routes.ts'screateWorkflowCatalogAdminRoutes, mounted inapps/hubat/api/workflow-catalog-admin), resolving a model's canonical name and a provider's name against this tenant's own catalog before writing, and refusing rather than guessing when either name isn't found.create_offeringanddisable_offeringareapproval: "ask";set_offering_priorityonly reorders an offering already live, so it stays ungated.@corbits/catalog-toolsto0.0.4fortool-package-freshness, and bumped theworkflows/assistanttool-package pin to match.model:*/model-provider:*read andmodel-offering:*read/create/manage grants these routes'requireGrantcalls need are planted on Myra's own run principal (ASSISTANT_RUN_PRINCIPAL_GRANTS, alongside CL-7467's access-tools grants), not tenant-wide viaSEED_GRANTS— a tenant-wide grant would let every seeded principal administer the catalog, not just Myra.@corbits/catalog-tools/offerings→@corbits/catalog-tools/off) soset_offering_priority's qualified wire name fits the 64-char OpenAI-compatible tool-name cap.Hub auth wiring
A workflow child authenticates with only its sidecar bearer token and run address, never a browser session, so it cannot reach the tenant-admin catalog routes (
vendor/intx/hub-api/src/routes/{models,model-providers,model-offerings}.ts), which sit behindresolveTenantand accept only a session cookie.packages/catalog-tools/src/routes.tsmounts a workflow-run-authenticated mirror at/api/workflow-catalog-admininstead: it resolves the caller's tenant/principal the same way@corbits/artifacts-hub'screateWorkflowRunAuthenticatorresolves every other workflow-run mount inapps/hub, and authorizes through the samecreateRequireGrant/idResourceagainst the same grant store and condition registry every tenant-session route gates on. Every offering write pushes the samepushSourceUpdatesSubtreesidecar refresh the tenant-session routes push, using the samesidecarRouter/credentialCipheralready wired inapps/hub/src/index.ts. The admin client (packages/catalog-tools/src/client.ts) now points at this new mount and no longer carries atenantId— the hub resolves the tenant from the sidecar credential the same way it already does for the read-only/api/workflow-inference-catalogsurface.Those tenant-admin route handlers (
createModelCatalogRoutes/createModelProviderRoutes/createModelOfferingRoutes) aren't exported from@intx/hub-api's public surface, soroutes.tsreimplements only their thin handler bodies against the sharedmodel/modelProvider/modelOfferingschema and@intx/typesresponse shapes — never the grant-store authorization itself, and never a second copy ofpushSourceUpdatesSubtree.Review follow-up
createModelCatalogRoutes/createModelProviderRoutes/createModelOfferingRoutesgenuinely aren't reachable:@intx/hub-api'spackage.jsonexportsmap publishes only"."(src/index.ts), and that entry point never re-exports the route factories (vendor/intx/hub-api/src/routes/model-offerings.ts:87). Delegating to them outright would require either editing that exports map —vendor/intx/hub-apiis vendored and never hand-edited — or a relative import reaching past a workspace package's declared surface, a pattern no other package in this repo uses. The mount stays the thin, heavily-cross-referenced reimplementation described above.?? eq(x.id, x.id)fallback after each cursoror()call inroutes.ts— both branches are always defined, soor()never actually returns undefined there. Replaced it with the same never-taken?? sql\false`fallbackvendor/intx/hub-api's owncursorCondition` uses for the identical case.packages/tool-registry-publish/src/pack.test.ts(which already packs and re-imports every@corbits/*-toolspackage's tarball) that bothcatalogToolsandcatalogOfferingToolsresolve by id from the packedtool.mjs, so a bundle silently dropped fromindex.ts's re-exports would fail this test instead of only showing up at deploy time.Grant scoping
Grants land on Myra's own run principal, derived the same deterministic
(tenantId, deploymentId)way CL-7467's access-tools grants are (plantAssistantRunPrincipalGrants, renamed fromplantAssistantAccessToolsGrantsnow that it plants both sets), not on the tenant's shared principal.SEED_GRANTSno longer carries the catalog-offering resource/action pairs.Test plan
bunx tsc --noEmit -p packages/catalog-toolsbunx tsc --noEmit -p apps/hubbunx tsc --noEmit -p packages/seedingbun run scripts/typecheck.ts(full repo)bun test packages/catalog-tools packages/seeding(103 pass)bun test packages/tool-registry-publish(69 pass)bun run check:structural report-error tool-package-pins tool-package-freshnessResolves CL-7468