Skip to content

Commit 2364437

Browse files
authored
Merge pull request #1092 from objectstack-ai/claude/fix-ai-chat-object-retrieval
2 parents bebd18c + 862ab8e commit 2364437

File tree

1 file changed

+64
-3
lines changed

1 file changed

+64
-3
lines changed

packages/objectql/src/plugin.ts

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,16 @@ export class ObjectQLPlugin implements Plugin {
129129
// object registered by plugins (e.g., sys_user from plugin-auth).
130130
await this.syncRegisteredSchemas(ctx);
131131

132+
// Bridge all SchemaRegistry objects to metadata service
133+
// This ensures AI tools and other IMetadataService consumers can see all objects
134+
await this.bridgeObjectsToMetadataService(ctx);
135+
132136
// Register built-in audit hooks
133137
this.registerAuditHooks(ctx);
134138

135139
// Register tenant isolation middleware
136140
this.registerTenantMiddleware(ctx);
137-
141+
138142
ctx.logger.info('ObjectQL engine started', {
139143
driversRegistered: this.ql?.['drivers']?.size || 0,
140144
objectsRegistered: this.ql?.registry?.getAllObjects?.()?.length || 0
@@ -387,12 +391,12 @@ export class ObjectQLPlugin implements Plugin {
387391
return;
388392
}
389393

390-
// Phase 2: DB hydration
394+
// Phase 2: DB hydration (loads into SchemaRegistry)
391395
try {
392396
const { loaded, errors } = await protocol.loadMetaFromDb();
393397

394398
if (loaded > 0 || errors > 0) {
395-
ctx.logger.info('Metadata restored from database', { loaded, errors });
399+
ctx.logger.info('Metadata restored from database to SchemaRegistry', { loaded, errors });
396400
} else {
397401
ctx.logger.debug('No persisted metadata found in database');
398402
}
@@ -404,6 +408,63 @@ export class ObjectQLPlugin implements Plugin {
404408
}
405409
}
406410

411+
/**
412+
* Bridge all SchemaRegistry objects to the metadata service.
413+
*
414+
* This ensures objects registered by plugins and loaded from sys_metadata
415+
* are visible to AI tools and other consumers that query IMetadataService.
416+
*
417+
* Runs after both restoreMetadataFromDb() and syncRegisteredSchemas() to
418+
* catch all objects in the SchemaRegistry regardless of their source.
419+
*/
420+
private async bridgeObjectsToMetadataService(ctx: PluginContext): Promise<void> {
421+
try {
422+
const metadataService = ctx.getService<any>('metadata');
423+
if (!metadataService || typeof metadataService.register !== 'function') {
424+
ctx.logger.debug('Metadata service unavailable for bridging, skipping');
425+
return;
426+
}
427+
428+
if (!this.ql?.registry) {
429+
ctx.logger.debug('SchemaRegistry unavailable for bridging, skipping');
430+
return;
431+
}
432+
433+
const objects = this.ql.registry.getAllObjects();
434+
let bridged = 0;
435+
436+
for (const obj of objects) {
437+
try {
438+
// Check if object is already in metadata service to avoid duplicates
439+
const existing = await metadataService.getObject(obj.name);
440+
if (!existing) {
441+
// Register object that exists in SchemaRegistry but not in metadata service
442+
await metadataService.register('object', obj.name, obj);
443+
bridged++;
444+
}
445+
} catch (e: unknown) {
446+
ctx.logger.debug('Failed to bridge object to metadata service', {
447+
object: obj.name,
448+
error: e instanceof Error ? e.message : String(e),
449+
});
450+
}
451+
}
452+
453+
if (bridged > 0) {
454+
ctx.logger.info('Bridged objects from SchemaRegistry to metadata service', {
455+
count: bridged,
456+
total: objects.length
457+
});
458+
} else {
459+
ctx.logger.debug('No objects needed bridging (all already in metadata service)');
460+
}
461+
} catch (e: unknown) {
462+
ctx.logger.debug('Failed to bridge objects to metadata service', {
463+
error: e instanceof Error ? e.message : String(e),
464+
});
465+
}
466+
}
467+
407468
/**
408469
* Load metadata from external metadata service into ObjectQL registry
409470
* This enables ObjectQL to use file-based or remote metadata

0 commit comments

Comments
 (0)