-
Notifications
You must be signed in to change notification settings - Fork 1
Fix AI chat object visibility by bridging SchemaRegistry to metadata service #1092
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,12 +129,16 @@ export class ObjectQLPlugin implements Plugin { | |
| // object registered by plugins (e.g., sys_user from plugin-auth). | ||
| await this.syncRegisteredSchemas(ctx); | ||
|
|
||
| // Bridge all SchemaRegistry objects to metadata service | ||
| // This ensures AI tools and other IMetadataService consumers can see all objects | ||
| await this.bridgeObjectsToMetadataService(ctx); | ||
|
|
||
| // Register built-in audit hooks | ||
| this.registerAuditHooks(ctx); | ||
|
|
||
| // Register tenant isolation middleware | ||
| this.registerTenantMiddleware(ctx); | ||
|
|
||
| ctx.logger.info('ObjectQL engine started', { | ||
| driversRegistered: this.ql?.['drivers']?.size || 0, | ||
| objectsRegistered: this.ql?.registry?.getAllObjects?.()?.length || 0 | ||
|
|
@@ -387,12 +391,12 @@ export class ObjectQLPlugin implements Plugin { | |
| return; | ||
| } | ||
|
|
||
| // Phase 2: DB hydration | ||
| // Phase 2: DB hydration (loads into SchemaRegistry) | ||
| try { | ||
| const { loaded, errors } = await protocol.loadMetaFromDb(); | ||
|
|
||
| if (loaded > 0 || errors > 0) { | ||
| ctx.logger.info('Metadata restored from database', { loaded, errors }); | ||
| ctx.logger.info('Metadata restored from database to SchemaRegistry', { loaded, errors }); | ||
| } else { | ||
| ctx.logger.debug('No persisted metadata found in database'); | ||
| } | ||
|
|
@@ -404,6 +408,63 @@ export class ObjectQLPlugin implements Plugin { | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Bridge all SchemaRegistry objects to the metadata service. | ||
| * | ||
| * This ensures objects registered by plugins and loaded from sys_metadata | ||
| * are visible to AI tools and other consumers that query IMetadataService. | ||
| * | ||
| * Runs after both restoreMetadataFromDb() and syncRegisteredSchemas() to | ||
| * catch all objects in the SchemaRegistry regardless of their source. | ||
| */ | ||
| private async bridgeObjectsToMetadataService(ctx: PluginContext): Promise<void> { | ||
| try { | ||
| const metadataService = ctx.getService<any>('metadata'); | ||
| if (!metadataService || typeof metadataService.register !== 'function') { | ||
| ctx.logger.debug('Metadata service unavailable for bridging, skipping'); | ||
| return; | ||
| } | ||
|
Comment on lines
+421
to
+426
|
||
|
|
||
| if (!this.ql?.registry) { | ||
| ctx.logger.debug('SchemaRegistry unavailable for bridging, skipping'); | ||
| return; | ||
| } | ||
|
|
||
| const objects = this.ql.registry.getAllObjects(); | ||
| let bridged = 0; | ||
|
|
||
| for (const obj of objects) { | ||
| try { | ||
| // Check if object is already in metadata service to avoid duplicates | ||
| const existing = await metadataService.getObject(obj.name); | ||
| if (!existing) { | ||
| // Register object that exists in SchemaRegistry but not in metadata service | ||
| await metadataService.register('object', obj.name, obj); | ||
| bridged++; | ||
|
Comment on lines
+439
to
+443
|
||
| } | ||
| } catch (e: unknown) { | ||
| ctx.logger.debug('Failed to bridge object to metadata service', { | ||
| object: obj.name, | ||
| error: e instanceof Error ? e.message : String(e), | ||
| }); | ||
| } | ||
| } | ||
|
|
||
|
Comment on lines
+433
to
+452
|
||
| if (bridged > 0) { | ||
| ctx.logger.info('Bridged objects from SchemaRegistry to metadata service', { | ||
| count: bridged, | ||
| total: objects.length | ||
| }); | ||
| } else { | ||
| ctx.logger.debug('No objects needed bridging (all already in metadata service)'); | ||
| } | ||
| } catch (e: unknown) { | ||
| ctx.logger.debug('Failed to bridge objects to metadata service', { | ||
| error: e instanceof Error ? e.message : String(e), | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Load metadata from external metadata service into ObjectQL registry | ||
| * This enables ObjectQL to use file-based or remote metadata | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New behavior (bridging SchemaRegistry objects into IMetadataService on startup) isn’t covered by tests. Since packages/objectql has integration tests for plugin startup ordering and metadata restoration, please add coverage asserting that: (1) plugin-registered and DB-restored objects become visible via metadataService.listObjects(), and (2) bridging is a no-op when metadata service is unavailable.