diff --git a/apps/api/package.json b/apps/api/package.json index f0b3c462..53f14f19 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -37,6 +37,7 @@ "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", "@nestjs/schedule": "^6.1.1", + "@nexiom/ai-engine": "workspace:*", "@nexiom/auth": "workspace:*", "@nexiom/cache": "workspace:*", "@nexiom/credentials": "workspace:*", @@ -46,6 +47,7 @@ "@nexiom/identity": "workspace:*", "@nexiom/piece-framework": "workspace:*", "@nexiom/piece-quickbooks": "workspace:*", + "@nexiom/piece-registry": "workspace:*", "@nexiom/piece-salesforce": "workspace:*", "@nexiom/queue": "workspace:*", "ai": "^6.0.146", diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 3c2a71dc..6aa88c67 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -19,7 +19,8 @@ import * as schema from '../db/schema.js'; import { ConnectionsModule } from '../modules/connections/connections.module.js'; import { TriggerModule } from '../modules/trigger/trigger.module.js'; import { EmailModule } from '../modules/email/email.module.js'; -import { StorageResolverModule, PiecesModule } from '@nexiom/engine'; +import { StorageResolverModule } from '@nexiom/engine'; +import { PiecesModule } from '@nexiom/piece-registry'; import { CacheModule } from '@nexiom/cache'; import { QueueModule, createQueueModuleOptions } from '@nexiom/queue'; import { DbManagerModule } from '../modules/dbmanager/dbmanager.module.js'; @@ -33,7 +34,7 @@ import { ObservabilityModule } from '../modules/observability/observability.modu import { TraceModule } from '../modules/trace/trace.module.js'; import { ExceptionsModule } from '../modules/exceptions/exceptions.module.js'; import { AiModule } from '../modules/ai/ai.module.js'; -import { MetadataModule } from '../modules/metadata/metadata.module.js'; +import { MetadataModule } from '@nexiom/piece-registry'; @Module({ imports: [ diff --git a/apps/api/src/modules/ai/ai.module.ts b/apps/api/src/modules/ai/ai.module.ts index cee616e3..81ab5f7d 100644 --- a/apps/api/src/modules/ai/ai.module.ts +++ b/apps/api/src/modules/ai/ai.module.ts @@ -1,32 +1,13 @@ import { Module } from '@nestjs/common'; import { ObservabilityModule } from '../observability/observability.module.js'; -import { AiController } from './_controllers/ai.controller.js'; -import { OrchestratorService } from './_services/orchestrator.service.js'; -import { AiRateLimitGuard } from './_interceptors/ai-ratelimit.guard.js'; -import { AiTelemetryInterceptor } from './_interceptors/ai-telemetry.interceptor.js'; -import { ConnectionsModule } from '../connections/connections.module.js'; -import { StitchesModule } from '../stitches/stitches.module.js'; -import { MetadataModule } from '../metadata/metadata.module.js'; +import { AiController } from './controllers/ai.controller.js'; +import { AiRateLimitGuard } from './interceptors/ai-ratelimit.guard.js'; +import { AiTelemetryInterceptor } from './interceptors/ai-telemetry.interceptor.js'; +import { AiEngineModule } from '@nexiom/ai-engine'; -/** - * AiModule - * - * - ObservabilityModule is imported to make @InjectPinoLogger available for - * OrchestratorService, AiRateLimitGuard, and AiTelemetryInterceptor. - * - ConnectionsModule provides TokenManagerService (credential fetching + refresh). - * - MetadataModule provides MetadataDiscoveryService (cached relation graphs). - * - PiecesModule is intentionally NOT imported — already registered globally - * via AppModule.PiecesModule.forRoot(), so PieceRegistryService is injectable. - * - CacheModule is likewise global via AppModule. - */ @Module({ - imports: [ - ObservabilityModule, - ConnectionsModule, - StitchesModule, - MetadataModule, - ], + imports: [ObservabilityModule, AiEngineModule], controllers: [AiController], - providers: [OrchestratorService, AiRateLimitGuard, AiTelemetryInterceptor], + providers: [AiRateLimitGuard, AiTelemetryInterceptor], }) export class AiModule {} diff --git a/apps/api/src/modules/ai/_controllers/ai.controller.spec.ts b/apps/api/src/modules/ai/controllers/ai.controller.spec.ts similarity index 96% rename from apps/api/src/modules/ai/_controllers/ai.controller.spec.ts rename to apps/api/src/modules/ai/controllers/ai.controller.spec.ts index 7b963304..60dbb021 100644 --- a/apps/api/src/modules/ai/_controllers/ai.controller.spec.ts +++ b/apps/api/src/modules/ai/controllers/ai.controller.spec.ts @@ -2,9 +2,9 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { Test, TestingModule } from '@nestjs/testing'; import { AuthGuard } from '@nexiom/auth'; -import { AiRateLimitGuard } from '../_interceptors/ai-ratelimit.guard.js'; +import { AiRateLimitGuard } from '../interceptors/ai-ratelimit.guard.js'; import { AiController } from './ai.controller.js'; -import { OrchestratorService } from '../_services/orchestrator.service.js'; +import { OrchestratorService } from '@nexiom/ai-engine'; import { PinoLogger } from 'nestjs-pino'; import { Response } from 'express'; import { PassThrough } from 'stream'; diff --git a/apps/api/src/modules/ai/_controllers/ai.controller.ts b/apps/api/src/modules/ai/controllers/ai.controller.ts similarity index 87% rename from apps/api/src/modules/ai/_controllers/ai.controller.ts rename to apps/api/src/modules/ai/controllers/ai.controller.ts index ce05f585..c2efb5e4 100644 --- a/apps/api/src/modules/ai/_controllers/ai.controller.ts +++ b/apps/api/src/modules/ai/controllers/ai.controller.ts @@ -11,10 +11,9 @@ import { ValidationPipe, } from '@nestjs/common'; import { AuthGuard } from '@nexiom/auth'; -import { AiRateLimitGuard } from '../_interceptors/ai-ratelimit.guard.js'; -import { AiTelemetryInterceptor } from '../_interceptors/ai-telemetry.interceptor.js'; -import { OrchestratorService } from '../_services/orchestrator.service.js'; -import { ChatRequest } from '../_types/chat-request.types.js'; +import { AiRateLimitGuard } from '../interceptors/ai-ratelimit.guard.js'; +import { AiTelemetryInterceptor } from '../interceptors/ai-telemetry.interceptor.js'; +import { OrchestratorService, ChatRequest } from '@nexiom/ai-engine'; import type { UIMessage } from 'ai'; import { PinoLogger } from 'nestjs-pino'; diff --git a/apps/api/src/modules/ai/_interceptors/ai-ratelimit.guard.ts b/apps/api/src/modules/ai/interceptors/ai-ratelimit.guard.ts similarity index 100% rename from apps/api/src/modules/ai/_interceptors/ai-ratelimit.guard.ts rename to apps/api/src/modules/ai/interceptors/ai-ratelimit.guard.ts diff --git a/apps/api/src/modules/ai/_interceptors/ai-telemetry.interceptor.ts b/apps/api/src/modules/ai/interceptors/ai-telemetry.interceptor.ts similarity index 100% rename from apps/api/src/modules/ai/_interceptors/ai-telemetry.interceptor.ts rename to apps/api/src/modules/ai/interceptors/ai-telemetry.interceptor.ts diff --git a/apps/api/src/modules/connections/connections.module.ts b/apps/api/src/modules/connections/connections.module.ts index 3f9b8606..b3cc11f2 100644 --- a/apps/api/src/modules/connections/connections.module.ts +++ b/apps/api/src/modules/connections/connections.module.ts @@ -13,7 +13,7 @@ import { ConnectorsController } from './connections/connectors.controller.js'; import { DefaultOAuthRefreshClient } from './connections/token-refresh.service.js'; import { ConnectorsService } from './connectors.service.js'; import { OauthStateService } from './oauth-state.service.js'; -import { PiecesModule } from '@nexiom/engine'; +import { PiecesModule } from '@nexiom/piece-registry'; import { DATABASE_CONNECTION } from '@nexiom/database'; import { type DrizzleDb } from '@nexiom/database'; diff --git a/apps/api/src/modules/connections/connections/callback.controller.spec.ts b/apps/api/src/modules/connections/connections/callback.controller.spec.ts index 1210bfe9..87812af8 100644 --- a/apps/api/src/modules/connections/connections/callback.controller.spec.ts +++ b/apps/api/src/modules/connections/connections/callback.controller.spec.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/unbound-method */ import { Test, TestingModule } from '@nestjs/testing'; import { OAuthCallbackController } from './callback.controller.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { Piece } from '@nexiom/piece-framework'; import type { Request, Response } from 'express'; import { vi, describe, it, expect, beforeEach } from 'vitest'; diff --git a/apps/api/src/modules/connections/connections/callback.controller.ts b/apps/api/src/modules/connections/connections/callback.controller.ts index 47373054..925b8f50 100644 --- a/apps/api/src/modules/connections/connections/callback.controller.ts +++ b/apps/api/src/modules/connections/connections/callback.controller.ts @@ -1,7 +1,7 @@ import { Controller, Get, Req, Res, Logger } from '@nestjs/common'; import type { Request, Response } from 'express'; import { ConfigService } from '@nestjs/config'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { OauthStateService } from '../oauth-state.service.js'; diff --git a/apps/api/src/modules/connections/connections/connectors.controller.spec.ts b/apps/api/src/modules/connections/connections/connectors.controller.spec.ts index fb0b32b2..d1e3fdd4 100644 --- a/apps/api/src/modules/connections/connections/connectors.controller.spec.ts +++ b/apps/api/src/modules/connections/connections/connectors.controller.spec.ts @@ -14,7 +14,7 @@ import { UnauthorizedException, HttpException, } from '@nestjs/common'; -import { PieceRegistryService, PIECES } from '@nexiom/engine'; +import { PieceRegistryService, PIECES } from '@nexiom/piece-registry'; import { describe, it, diff --git a/apps/api/src/modules/connections/connections/connectors.controller.ts b/apps/api/src/modules/connections/connections/connectors.controller.ts index 55ceeac1..aa841c2d 100644 --- a/apps/api/src/modules/connections/connections/connectors.controller.ts +++ b/apps/api/src/modules/connections/connections/connectors.controller.ts @@ -37,7 +37,7 @@ import { member, } from '@nexiom/database'; import { eq, and, count, desc } from 'drizzle-orm'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { ConnectionValueBlob } from '../connectors.service.js'; import { REDIS_CLIENT, type Redis } from '@nexiom/cache'; import { CreateOAuthSession } from '../validation/create-oauth-session.js'; diff --git a/apps/api/src/modules/connections/connections/token-refresh.service.spec.ts b/apps/api/src/modules/connections/connections/token-refresh.service.spec.ts index c440d3e0..cf363fa1 100644 --- a/apps/api/src/modules/connections/connections/token-refresh.service.spec.ts +++ b/apps/api/src/modules/connections/connections/token-refresh.service.spec.ts @@ -1,6 +1,6 @@ import { DefaultOAuthRefreshClient } from './token-refresh.service.js'; import { EncryptionService, OAuthRefreshError } from '@nexiom/credentials'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { Piece } from '@nexiom/piece-framework'; import { describe, diff --git a/apps/api/src/modules/connections/connections/token-refresh.service.ts b/apps/api/src/modules/connections/connections/token-refresh.service.ts index 5e02d903..b417c8c7 100644 --- a/apps/api/src/modules/connections/connections/token-refresh.service.ts +++ b/apps/api/src/modules/connections/connections/token-refresh.service.ts @@ -14,7 +14,7 @@ import { } from '@nexiom/database'; import { eq, and, desc } from 'drizzle-orm'; import type { ConnectionValueBlob } from '../connectors.service.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; @Injectable() export class DefaultOAuthRefreshClient implements OAuthRefreshClient { diff --git a/apps/api/src/modules/connections/connectors.service.spec.ts b/apps/api/src/modules/connections/connectors.service.spec.ts index 73478f66..21e74777 100644 --- a/apps/api/src/modules/connections/connectors.service.spec.ts +++ b/apps/api/src/modules/connections/connectors.service.spec.ts @@ -3,7 +3,7 @@ import { DATABASE_CONNECTION } from '@nexiom/database'; import { ConfigService } from '@nestjs/config'; import { ConnectorsService } from './connectors.service.js'; import { EncryptionService, AppCredentialError } from '@nexiom/credentials'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { Piece } from '@nexiom/piece-framework'; import { DB_MANAGER } from '../dbmanager/dbmanager.module.js'; import { SchemaPlan } from '@nexiom/dbmanager'; diff --git a/apps/api/src/modules/connections/connectors.service.ts b/apps/api/src/modules/connections/connectors.service.ts index 2480013f..7d78c76b 100644 --- a/apps/api/src/modules/connections/connectors.service.ts +++ b/apps/api/src/modules/connections/connectors.service.ts @@ -26,7 +26,7 @@ import { eq, and, or, sql } from 'drizzle-orm'; import { SchemaPlan } from '@nexiom/dbmanager'; import type { DatabaseManager } from '@nexiom/dbmanager'; import { DB_MANAGER } from '../dbmanager/dbmanager.module.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import * as crypto from 'node:crypto'; import { extractPgError, PG_UNIQUE_VIOLATION } from '../../shared/db.utils.js'; diff --git a/apps/api/src/modules/metadata/metadata.controller.spec.ts b/apps/api/src/modules/metadata/metadata.controller.spec.ts deleted file mode 100644 index daf42e27..00000000 --- a/apps/api/src/modules/metadata/metadata.controller.spec.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { Test } from '@nestjs/testing'; -import { AuthGuard, PermissionsGuard } from '@nexiom/auth'; -import { MetadataController } from './metadata.controller.js'; -import { MetadataDiscoveryService } from './metadata-discovery.service.js'; -import { ORG_ID, makeAuth } from '../workspaces/workspace-test-fixtures.js'; - -const CONN_ID = 'conn-uuid-1'; - -const mockService = { - describeObjects: vi.fn(), - describeFields: vi.fn(), - describeRelatedObjects: vi.fn(), - describeConfig: vi.fn(), -}; - -describe('MetadataController', () => { - let controller: MetadataController; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - controllers: [MetadataController], - providers: [{ provide: MetadataDiscoveryService, useValue: mockService }], - }) - .overrideGuard(AuthGuard) - .useValue({ canActivate: () => true }) - .overrideGuard(PermissionsGuard) - .useValue({ canActivate: () => true }) - .compile(); - - controller = module.get(MetadataController); - vi.clearAllMocks(); - }); - - it('describeObjects — delegates to service with orgId, connectionId, and limit', async () => { - const objects = [{ name: 'Contact', label: 'Contact', queryable: true }]; - mockService.describeObjects.mockResolvedValue(objects); - - const result = await controller.describeObjects( - makeAuth(), - CONN_ID, - 500, - false, - ); - - expect(result).toBe(objects); - expect(mockService.describeObjects).toHaveBeenCalledWith( - ORG_ID, - CONN_ID, - 500, - false, - ); - }); - - it('describeObjects — forwards refresh=true to service for cache-busting', async () => { - const objects = [{ name: 'Account', label: 'Account', queryable: true }]; - mockService.describeObjects.mockResolvedValue(objects); - - const result = await controller.describeObjects( - makeAuth(), - CONN_ID, - 500, - true, - ); - - expect(result).toBe(objects); - expect(mockService.describeObjects).toHaveBeenCalledWith( - ORG_ID, - CONN_ID, - 500, - true, - ); - }); - - it('describeFields — delegates to service with orgId, connectionId, and objectName', async () => { - const fields = [ - { - name: 'Id', - label: 'ID', - type: 'string', - filterable: true, - sortable: true, - nillable: false, - }, - ]; - mockService.describeFields.mockResolvedValue(fields); - - const result = await controller.describeFields( - makeAuth(), - CONN_ID, - 'Contact', - ); - - expect(result).toBe(fields); - expect(mockService.describeFields).toHaveBeenCalledWith( - ORG_ID, - CONN_ID, - 'Contact', - ); - }); - - it('describeRelatedObjects — delegates to service with orgId, connectionId, and objectName', async () => { - const rels = [ - { - objectName: 'Invoice', - relationshipType: 'CHILD', - relationField: 'accId', - }, - ]; - mockService.describeRelatedObjects.mockResolvedValue(rels); - - const result = await controller.describeRelatedObjects( - makeAuth(), - CONN_ID, - 'Account', - ); - - expect(result).toBe(rels); - expect(mockService.describeRelatedObjects).toHaveBeenCalledWith( - ORG_ID, - CONN_ID, - 'Account', - ); - }); - - it('describeConfig — delegates to service with orgId and connectionId', async () => { - const config = [{ key: 'env', type: 'string' }]; - mockService.describeConfig.mockResolvedValue(config); - - const result = await controller.describeConfig(makeAuth(), CONN_ID); - - expect(result).toBe(config); - expect(mockService.describeConfig).toHaveBeenCalledWith(ORG_ID, CONN_ID); - }); - - it('validateObjectName — guards against Redis injection by throwing BadRequestException on invalid characters', () => { - expect(() => - controller.describeFields(makeAuth(), CONN_ID, 'Invali@d*Name'), - ).toThrow('objectName must be 1-255 alphanumeric/underscore characters'); - - expect(() => - controller.describeRelatedObjects(makeAuth(), CONN_ID, ''), - ).toThrow('objectName must be 1-255 alphanumeric/underscore characters'); - }); -}); diff --git a/apps/api/src/modules/metadata/metadata.controller.ts b/apps/api/src/modules/metadata/metadata.controller.ts deleted file mode 100644 index 202bead1..00000000 --- a/apps/api/src/modules/metadata/metadata.controller.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { - Controller, - Get, - Param, - Query, - ParseUUIDPipe, - ParseIntPipe, - DefaultValuePipe, - ParseBoolPipe, - UseGuards, - BadRequestException, -} from '@nestjs/common'; -import { - AuthGuard, - PermissionsGuard, - RequirePermission, - AuthContext, - type RequestAuthContext, -} from '@nexiom/auth'; -import { MetadataDiscoveryService } from './metadata-discovery.service.js'; -import { requireOrgId } from '../workspaces/workspace.utils.js'; - -function validateObjectName(objectName: string) { - if (!/^[\w]{1,255}$/.test(objectName)) { - throw new BadRequestException( - 'objectName must be 1-255 alphanumeric/underscore characters.', - ); - } -} - -@UseGuards(AuthGuard, PermissionsGuard) -@Controller('stitches/metadata') -export class MetadataController { - constructor(private readonly metadataDiscovery: MetadataDiscoveryService) {} - - @Get(':connectionId/objects') - @RequirePermission('stitches', 'read') - describeObjects( - @AuthContext() auth: RequestAuthContext, - @Param('connectionId', ParseUUIDPipe) connectionId: string, - @Query('limit', new DefaultValuePipe(500), ParseIntPipe) limit: number, - @Query('refresh', new DefaultValuePipe(false), ParseBoolPipe) - refresh: boolean, - ) { - return this.metadataDiscovery.describeObjects( - requireOrgId(auth), - connectionId, - limit, - refresh, - ); - } - - @Get(':connectionId/objects/:objectName/fields') - @RequirePermission('stitches', 'read') - describeFields( - @AuthContext() auth: RequestAuthContext, - @Param('connectionId', ParseUUIDPipe) connectionId: string, - @Param('objectName') objectName: string, - ) { - // Restrict to safe characters: vendor object names are alphanumeric + underscore. - // Prevents Redis key injection and ensures URL-safe values. - validateObjectName(objectName); - return this.metadataDiscovery.describeFields( - requireOrgId(auth), - connectionId, - objectName, - ); - } - - @Get(':connectionId/objects/:objectName/related') - @RequirePermission('stitches', 'read') - describeRelatedObjects( - @AuthContext() auth: RequestAuthContext, - @Param('connectionId', ParseUUIDPipe) connectionId: string, - @Param('objectName') objectName: string, - ) { - validateObjectName(objectName); - return this.metadataDiscovery.describeRelatedObjects( - requireOrgId(auth), - connectionId, - objectName, - ); - } - - @Get(':connectionId/config') - @RequirePermission('stitches', 'read') - describeConfig( - @AuthContext() auth: RequestAuthContext, - @Param('connectionId', ParseUUIDPipe) connectionId: string, - ) { - return this.metadataDiscovery.describeConfig( - requireOrgId(auth), - connectionId, - ); - } -} diff --git a/apps/api/src/modules/metadata/metadata.module.ts b/apps/api/src/modules/metadata/metadata.module.ts deleted file mode 100644 index c338028d..00000000 --- a/apps/api/src/modules/metadata/metadata.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Module } from '@nestjs/common'; -import { AuthModule } from '@nexiom/auth'; -import { CacheModule } from '@nexiom/cache'; -import { DbModule } from '../../db/db.module.js'; -import { PiecesModule } from '@nexiom/engine'; -import { ConnectionsModule } from '../connections/connections.module.js'; -import { MetadataController } from './metadata.controller.js'; -import { MetadataDiscoveryService } from './metadata-discovery.service.js'; - -@Module({ - imports: [DbModule, AuthModule, CacheModule, PiecesModule, ConnectionsModule], - controllers: [MetadataController], - providers: [MetadataDiscoveryService], - exports: [MetadataDiscoveryService], -}) -export class MetadataModule {} diff --git a/apps/api/src/modules/scheduler/poll-sync-runner.spec.ts b/apps/api/src/modules/scheduler/poll-sync-runner.spec.ts index f0e9c4a2..bd08c88b 100644 --- a/apps/api/src/modules/scheduler/poll-sync-runner.spec.ts +++ b/apps/api/src/modules/scheduler/poll-sync-runner.spec.ts @@ -10,7 +10,8 @@ import { } from '@nexiom/database'; import { REDIS_CLIENT } from '@nexiom/cache'; import { TokenManagerService } from '@nexiom/credentials'; -import { CursorManagerService, PieceRegistryService } from '@nexiom/engine'; +import { CursorManagerService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { StreamDescriptor, PollPage, PollRecord } from '@nexiom/engine'; import { SyncRunner } from './sync-runner.js'; import { PollSyncRunner } from './poll-sync-runner.js'; diff --git a/apps/api/src/modules/scheduler/poll-sync-runner.ts b/apps/api/src/modules/scheduler/poll-sync-runner.ts index 580fc84f..f84a183e 100644 --- a/apps/api/src/modules/scheduler/poll-sync-runner.ts +++ b/apps/api/src/modules/scheduler/poll-sync-runner.ts @@ -27,7 +27,7 @@ import { type StreamDescriptor, type StreamResult, } from '@nexiom/engine'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { SyncRunner, type SyncResult } from './sync-runner.js'; import { pollLockKey } from './lock-keys.js'; diff --git a/apps/api/src/modules/scheduler/scheduler.module.ts b/apps/api/src/modules/scheduler/scheduler.module.ts index d30eaf15..981a4728 100644 --- a/apps/api/src/modules/scheduler/scheduler.module.ts +++ b/apps/api/src/modules/scheduler/scheduler.module.ts @@ -1,11 +1,8 @@ import { Module, type Type } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { ConfigService } from '@nestjs/config'; -import { - CursorManagerService, - PiecesModule, - PieceRegistryService, -} from '@nexiom/engine'; +import { CursorManagerService } from '@nexiom/engine'; +import { PiecesModule, PieceRegistryService } from '@nexiom/piece-registry'; import { TokenManagerService } from '@nexiom/credentials'; import { REDIS_CLIENT } from '@nexiom/cache'; import { DATABASE_CONNECTION } from '@nexiom/database'; diff --git a/apps/api/src/modules/stitches/stitches.module.ts b/apps/api/src/modules/stitches/stitches.module.ts index 6da7db5a..af33fc0b 100644 --- a/apps/api/src/modules/stitches/stitches.module.ts +++ b/apps/api/src/modules/stitches/stitches.module.ts @@ -3,20 +3,18 @@ import { AuthModule } from '@nexiom/auth'; import { CacheModule } from '@nexiom/cache'; import { EncryptionService, AesEncryptionService } from '@nexiom/credentials'; import { DbModule } from '../../db/db.module.js'; -import { PiecesModule } from '@nexiom/engine'; import { ConnectionsModule } from '../connections/connections.module.js'; import { StitchesController } from './stitches.controller.js'; import { StitchesAdminController } from './stitches-admin.controller.js'; import { FieldMappingsController } from './field-mappings.controller.js'; import { StitchesService } from './stitches.service.js'; -import { MetadataModule } from '../metadata/metadata.module.js'; +import { MetadataModule } from '@nexiom/piece-registry'; @Module({ imports: [ DbModule, AuthModule, CacheModule, - PiecesModule, ConnectionsModule, MetadataModule, ], diff --git a/apps/api/src/modules/trigger/dlq-processor.service.spec.ts b/apps/api/src/modules/trigger/dlq-processor.service.spec.ts index 36a04dac..b3a59b65 100644 --- a/apps/api/src/modules/trigger/dlq-processor.service.spec.ts +++ b/apps/api/src/modules/trigger/dlq-processor.service.spec.ts @@ -3,7 +3,7 @@ import { DlqProcessorService } from './dlq-processor.service.js'; /* eslint-disable @typescript-eslint/unbound-method */ import { TriggerStrategy } from '@nexiom/piece-framework'; import type { TriggerExecutorService } from './trigger-executor.service.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; /** * Minimal Redis mock that supports the DLQ surface: diff --git a/apps/api/src/modules/trigger/dlq-processor.service.ts b/apps/api/src/modules/trigger/dlq-processor.service.ts index c32215f2..3e940bbd 100644 --- a/apps/api/src/modules/trigger/dlq-processor.service.ts +++ b/apps/api/src/modules/trigger/dlq-processor.service.ts @@ -7,7 +7,7 @@ import { type WebhookRunParams, type TriggerRunParams, } from './trigger-executor.service.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; const MAX_ATTEMPTS = 3; diff --git a/apps/api/src/modules/trigger/poller.service.spec.ts b/apps/api/src/modules/trigger/poller.service.spec.ts index 3f7d7841..040e4cb0 100644 --- a/apps/api/src/modules/trigger/poller.service.spec.ts +++ b/apps/api/src/modules/trigger/poller.service.spec.ts @@ -3,7 +3,7 @@ import { PollerService } from './poller.service.js'; /* eslint-disable @typescript-eslint/unbound-method */ import { TriggerStrategy } from '@nexiom/piece-framework'; import type { TriggerExecutorService } from './trigger-executor.service.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; function makeDb(rows: unknown[] = []) { return { diff --git a/apps/api/src/modules/trigger/poller.service.ts b/apps/api/src/modules/trigger/poller.service.ts index 50c09768..a50c4017 100644 --- a/apps/api/src/modules/trigger/poller.service.ts +++ b/apps/api/src/modules/trigger/poller.service.ts @@ -3,7 +3,7 @@ import { Cron, CronExpression } from '@nestjs/schedule'; import type { DrizzleDb } from '@nexiom/database'; import { DATABASE_CONNECTION } from '@nexiom/database'; import { TriggerExecutorService } from './trigger-executor.service.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; interface ActiveConnection { workspace_id: string; diff --git a/apps/api/src/modules/trigger/trigger.module.ts b/apps/api/src/modules/trigger/trigger.module.ts index fbf31d15..b17daaf3 100644 --- a/apps/api/src/modules/trigger/trigger.module.ts +++ b/apps/api/src/modules/trigger/trigger.module.ts @@ -2,7 +2,7 @@ import { Module } from '@nestjs/common'; import { DbModule } from '../../db/db.module.js'; import { REDIS_CLIENT } from '@nexiom/cache'; import type { Redis } from '@nexiom/cache'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { TriggerExecutorService } from './trigger-executor.service.js'; import { PollerService } from './poller.service.js'; import { DlqProcessorService } from './dlq-processor.service.js'; diff --git a/apps/api/src/modules/trigger/webhooks.controller.spec.ts b/apps/api/src/modules/trigger/webhooks.controller.spec.ts index d73227d4..8f55f904 100644 --- a/apps/api/src/modules/trigger/webhooks.controller.spec.ts +++ b/apps/api/src/modules/trigger/webhooks.controller.spec.ts @@ -3,7 +3,7 @@ import { describe, it, expect, beforeEach, vi, type Mock } from 'vitest'; import { WebhooksController } from './webhooks.controller.js'; import { NotFoundException, UnauthorizedException } from '@nestjs/common'; import { TriggerStrategy } from '@nexiom/piece-framework'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import type { TriggerExecutorService } from './trigger-executor.service.js'; function makeDb(row: unknown = null) { diff --git a/apps/api/src/modules/trigger/webhooks.controller.ts b/apps/api/src/modules/trigger/webhooks.controller.ts index 921a457e..d052da48 100644 --- a/apps/api/src/modules/trigger/webhooks.controller.ts +++ b/apps/api/src/modules/trigger/webhooks.controller.ts @@ -13,7 +13,7 @@ import { } from '@nestjs/common'; import type { DrizzleDb } from '@nexiom/database'; import { DATABASE_CONNECTION } from '@nexiom/database'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { TriggerExecutorService } from './trigger-executor.service.js'; interface ConnectionRow { diff --git a/apps/api/src/modules/webhooks/webhook-signature.guard.spec.ts b/apps/api/src/modules/webhooks/webhook-signature.guard.spec.ts index 69999127..ed954097 100644 --- a/apps/api/src/modules/webhooks/webhook-signature.guard.spec.ts +++ b/apps/api/src/modules/webhooks/webhook-signature.guard.spec.ts @@ -8,7 +8,7 @@ import { } from '@nestjs/common'; import { createHmac } from 'node:crypto'; import { WebhookSignatureGuard } from './webhook-signature.guard.js'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { DATABASE_CONNECTION } from '@nexiom/database'; import { getLoggerToken } from 'nestjs-pino'; import { WEBHOOK_RESOLVED_CONNECTION } from '../../guards/tenant-rate-limit.guard.js'; diff --git a/apps/api/src/modules/webhooks/webhook-signature.guard.ts b/apps/api/src/modules/webhooks/webhook-signature.guard.ts index 33511e99..919ddd40 100644 --- a/apps/api/src/modules/webhooks/webhook-signature.guard.ts +++ b/apps/api/src/modules/webhooks/webhook-signature.guard.ts @@ -13,7 +13,7 @@ import { InjectPinoLogger, PinoLogger } from 'nestjs-pino'; import { DATABASE_CONNECTION, appConnections } from '@nexiom/database'; import type { DrizzleDb } from '@nexiom/database'; import { eq } from 'drizzle-orm'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '@nexiom/piece-registry'; import { WEBHOOK_RESOLVED_CONNECTION, type WebhookResolvedConnection, diff --git a/apps/api/src/modules/webhooks/webhooks.module.ts b/apps/api/src/modules/webhooks/webhooks.module.ts index 5f34ed74..0a9d77cd 100644 --- a/apps/api/src/modules/webhooks/webhooks.module.ts +++ b/apps/api/src/modules/webhooks/webhooks.module.ts @@ -3,7 +3,8 @@ import { WebhooksController } from './webhooks.controller.js'; import { WebhookSignatureGuard } from './webhook-signature.guard.js'; import { TenantRateLimitGuard } from '../../guards/tenant-rate-limit.guard.js'; import { DbModule } from '../../db/db.module.js'; -import { StorageResolverModule, PiecesModule } from '@nexiom/engine'; +import { StorageResolverModule } from '@nexiom/engine'; +import { PiecesModule } from '@nexiom/piece-registry'; import { ObservabilityModule } from '../observability/observability.module.js'; // NOTE: TenantRateLimitGuard injects REDIS_CLIENT, which is provided by diff --git a/apps/worker/package.json b/apps/worker/package.json index 44f40833..21858ba4 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -45,6 +45,7 @@ "@nexiom/identity": "workspace:*", "@nexiom/piece-framework": "workspace:*", "@nexiom/piece-quickbooks": "workspace:*", + "@nexiom/piece-registry": "workspace:*", "@nexiom/piece-salesforce": "workspace:*", "@nexiom/queue": "workspace:*", "bcryptjs": "^3.0.3", diff --git a/apps/worker/src/app.module.ts b/apps/worker/src/app.module.ts index 5ab23fd7..82f263da 100644 --- a/apps/worker/src/app.module.ts +++ b/apps/worker/src/app.module.ts @@ -2,7 +2,7 @@ import { Module } from "@nestjs/common"; import { ScheduleModule } from "@nestjs/schedule"; import { PipelineModule } from "./modules/pipeline/pipeline.module.js"; import { ConfigModule, ConfigService } from "@nestjs/config"; -import { PiecesModule } from "@nexiom/engine"; +import { PiecesModule } from "@nexiom/piece-registry"; import { QueueModule, createQueueModuleOptions } from "@nexiom/queue"; @Module({ diff --git a/apps/worker/src/modules/pipeline/delivery.service.spec.ts b/apps/worker/src/modules/pipeline/delivery.service.spec.ts index a499ff8c..b431ccb9 100644 --- a/apps/worker/src/modules/pipeline/delivery.service.spec.ts +++ b/apps/worker/src/modules/pipeline/delivery.service.spec.ts @@ -3,7 +3,8 @@ import { Test, TestingModule } from "@nestjs/testing"; import { DeliveryService } from "./delivery.service.js"; import { QueueService, QueueName } from "@nexiom/queue"; import { DATABASE_CONNECTION } from "@nexiom/database"; -import { StorageResolverService, PieceRegistryService } from "@nexiom/engine"; +import { StorageResolverService } from "@nexiom/engine"; +import { PieceRegistryService } from "@nexiom/piece-registry"; import { TokenManagerService } from "@nexiom/credentials"; import { describe, it, expect, vi, beforeEach } from "vitest"; diff --git a/apps/worker/src/modules/pipeline/delivery.service.ts b/apps/worker/src/modules/pipeline/delivery.service.ts index 098ea7c0..404b9418 100644 --- a/apps/worker/src/modules/pipeline/delivery.service.ts +++ b/apps/worker/src/modules/pipeline/delivery.service.ts @@ -17,7 +17,8 @@ import { globalEntityMap, } from "@nexiom/database"; import type { DrizzleDb } from "@nexiom/database"; -import { StorageResolverService, PieceRegistryService } from "@nexiom/engine"; +import { StorageResolverService } from "@nexiom/engine"; +import { PieceRegistryService } from "@nexiom/piece-registry"; import { TokenManagerService } from "@nexiom/credentials"; import { RetryableException } from "@nexiom/piece-framework"; import { diff --git a/apps/worker/src/modules/pipeline/normalization.service.spec.ts b/apps/worker/src/modules/pipeline/normalization.service.spec.ts index 02cc7021..68783e90 100644 --- a/apps/worker/src/modules/pipeline/normalization.service.spec.ts +++ b/apps/worker/src/modules/pipeline/normalization.service.spec.ts @@ -3,7 +3,8 @@ import { Test, TestingModule } from "@nestjs/testing"; import { NormalizationService } from "./normalization.service.js"; import { QueueService, QueueName } from "@nexiom/queue"; import { DATABASE_CONNECTION } from "@nexiom/database"; -import { StorageResolverService, PieceRegistryService } from "@nexiom/engine"; +import { StorageResolverService } from "@nexiom/engine"; +import { PieceRegistryService } from "@nexiom/piece-registry"; import { describe, it, expect, vi, beforeEach } from "vitest"; describe("NormalizationService", () => { diff --git a/apps/worker/src/modules/pipeline/normalization.service.ts b/apps/worker/src/modules/pipeline/normalization.service.ts index e2186cd5..f3e491a0 100644 --- a/apps/worker/src/modules/pipeline/normalization.service.ts +++ b/apps/worker/src/modules/pipeline/normalization.service.ts @@ -14,7 +14,8 @@ import { appConnections, } from "@nexiom/database"; import type { DrizzleDb } from "@nexiom/database"; -import { StorageResolverService, PieceRegistryService } from "@nexiom/engine"; +import { StorageResolverService } from "@nexiom/engine"; +import { PieceRegistryService } from "@nexiom/piece-registry"; import { sql } from "drizzle-orm"; import { sanitizeError, diff --git a/apps/worker/src/modules/pipeline/pipeline.module.ts b/apps/worker/src/modules/pipeline/pipeline.module.ts index b7694a10..6836aa85 100644 --- a/apps/worker/src/modules/pipeline/pipeline.module.ts +++ b/apps/worker/src/modules/pipeline/pipeline.module.ts @@ -1,7 +1,8 @@ import { Module } from "@nestjs/common"; import { QueueModule } from "@nexiom/queue"; import { DbModule } from "../../db/db.module.js"; -import { StorageResolverModule, PiecesModule } from "@nexiom/engine"; +import { StorageResolverModule } from "@nexiom/engine"; +import { PiecesModule } from "@nexiom/piece-registry"; import { ReplicaService } from "./replica.service.js"; import { NormalizationService } from "./normalization.service.js"; diff --git a/docs/architecture/master/implementation-plan.md b/docs/architecture/master/implementation-plan.md index 83b4dca2..82de7d24 100644 --- a/docs/architecture/master/implementation-plan.md +++ b/docs/architecture/master/implementation-plan.md @@ -111,10 +111,10 @@ All infrastructure clients switch behaviour via a single `INFRA_MODE=local|produ | Queue | SQS → LocalStack port `4566` | SQS → AWS | | API Mocks | Piece HTTP calls → Prism `localhost:4010` | Piece HTTP calls → vendor URLs | -`packages/infra-adapters/` is a NestJS dynamic module — `EncryptionModule.forRootAsync()` registers the correct adapter as the `ENCRYPTION_SERVICE` provider. Consumers inject via token, never import a concrete adapter directly. +`packages/infra/` is a NestJS dynamic module — `EncryptionModule.forRootAsync()` registers the correct adapter as the `ENCRYPTION_SERVICE` provider. Consumers inject via token, never import a concrete adapter directly. ```typescript -// packages/infra-adapters/src/encryption.module.ts +// packages/infra/src/encryption.module.ts @Global() @Module({}) export class EncryptionModule { @@ -735,7 +735,7 @@ Phase 6 (Environments) ← can run in parallel with Phase 1 | --- | --- | | `docker-compose.yml` | Postgres, Redis, LocalStack (SQS+KMS), Prism, PgBouncer | | `packages/queue/` | SQS wrapper with `INFRA_MODE` switching | -| `packages/infra-adapters/` | `LocalCryptoAdapter`, `AwsKmsAdapter`, SQS client factory | +| `packages/infra/` | `LocalCryptoAdapter`, `AwsKmsAdapter` | | `packages/observability/` | Pino logger, OpenTelemetry tracer, `withSpan()` helper | | `packages/pieces/salesforce/openapi.json` | OpenAPI spec for Prism mocking | | `packages/pieces/quickbooks/openapi.json` | OpenAPI spec for Prism mocking | @@ -808,4 +808,4 @@ curl -X POST http://localhost:4000/webhooks/salesforce \ -d '{ "sobjectType": "rtms__Load__c", "Id": "SF-001", "Region": "US" }' ``` -Then open `http://localhost:3000` → Route Intelligence → see the L1→L6 green trace. +Then open `http://localhost:3000` → Route Intelligence → see the L1→L6 green trace. \ No newline at end of file diff --git a/docs/architecture/master/tasks.md b/docs/architecture/master/tasks.md index 5afa80b3..af017601 100644 --- a/docs/architecture/master/tasks.md +++ b/docs/architecture/master/tasks.md @@ -32,7 +32,7 @@ Each task is one commit (or one small PR). Checkboxes track completion. - Files: `packages/queue/src/queue.constants.ts`, `packages/queue/src/queue.interfaces.ts`, `packages/queue/src/queue.service.ts`, `packages/queue/src/queue.module.ts`, `packages/queue/src/index.ts`, `packages/queue/package.json` - Depends: T001 -### T004 · module: `packages/infra-adapters/` — `EncryptionModule` NestJS dynamic module +### T004 · module: `packages/infra/` — `EncryptionModule` NestJS dynamic module - [x] `encryption.constants.ts` — `ENCRYPTION_SERVICE` injection token - [x] `encryption.interface.ts` — `IEncryptionService` with `encrypt(plaintext: string): Promise` and `decrypt(ciphertext: string): Promise` @@ -41,7 +41,7 @@ Each task is one commit (or one small PR). Checkboxes track completion. - [x] `encryption.module.ts` — `EncryptionModule.forRootAsync(options): DynamicModule`; factory provider selects adapter via `INFRA_MODE`; exports `ENCRYPTION_SERVICE` token - [x] Consumers inject via `@Inject(ENCRYPTION_SERVICE) private readonly encryption: IEncryptionService` - [x] Unit tests — verify encrypt/decrypt round-trip for both adapters; test module wiring with `overrideProvider` -- Files: `packages/infra-adapters/src/encryption/**`, `packages/infra-adapters/src/index.ts`, `packages/infra-adapters/package.json` +- Files: `packages/infra/src/encryption/**`, `packages/infra/src/index.ts`, `packages/infra/package.json` - Depends: T001 ### T005 · script: `db:provision:local` diff --git a/docs/architecture/sync_strategy/sync_strategy.md b/docs/architecture/sync_strategy/sync_strategy.md index acd8ff27..09e1be6c 100644 --- a/docs/architecture/sync_strategy/sync_strategy.md +++ b/docs/architecture/sync_strategy/sync_strategy.md @@ -63,7 +63,7 @@ nexiom/ ├── queue/ SQS messaging ├── database/ Schema + migrations ├── cache/ Redis client - ├── infra-adapters/ KMS decryption, crypto + ├── infra/ KMS decryption, crypto ├── auth/ JWT, sessions ├── identity/ Tenant / org management ├── dbmanager/ Schema provisioner (ws_{id} plans) @@ -438,7 +438,7 @@ graph LR | Concern | Code | Responsibility | | :--- | :--- | :--- | -| **Platform** | `engine/platform/core/` + `packages/infra-adapters` + `packages/cache` | Manages AWS KMS decryption of tenant credentials, acquires the Redis Distributed Refresh Lock, hosts the Activepieces runtime environment that runs piece actions | +| **Platform** | `engine/platform/core/` + `packages/infra` + `packages/cache` | Manages AWS KMS decryption of tenant credentials, acquires the Redis Distributed Refresh Lock, hosts the Activepieces runtime environment that runs piece actions | | **Application** | `engine/application/pieces/{vendor}/actions/{action}.ts` | The Activepieces `run()` function for the specific target action (e.g., `quickbooks.create_invoice`): constructs and fires the final HTTP request to the destination API | --- @@ -463,4 +463,4 @@ graph LR | L3 | Normalization | Relational Enrichment, dependency fetch | Canonical Model mapping (`TMS_VENDOR`, etc.) | | L4 | Outbound Prep | Fat JSON assembly, Sync Condition evaluation | MappingEngine (80%) + Git Shard VM (20%) | | L5 | Delivery Engine | KMS decrypt, Redis lock, Activepieces runtime | `run()` → HTTP request to destination API | -| L6 | Destination Gateway | `outbound_gateway` log, GEM update | — (standardised) | +| L6 | Destination Gateway | `outbound_gateway` log, GEM update | — (standardised) | \ No newline at end of file diff --git a/engine/ai/core/package.json b/engine/ai/core/package.json new file mode 100644 index 00000000..aec6bddf --- /dev/null +++ b/engine/ai/core/package.json @@ -0,0 +1,43 @@ +{ + "name": "@nexiom/ai-engine", + "version": "1.0.0", + "type": "module", + "private": true, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc", + "test": "vitest run", + "test:watch": "vitest", + "test:cov": "vitest run --coverage" + }, + "dependencies": { + "@ai-sdk/google": "^3.0.58", + "@nestjs/common": "^11.0.1", + "@nexiom/credentials": "workspace:*", + "@nexiom/database": "workspace:*", + "@nexiom/piece-framework": "workspace:*", + "@nexiom/piece-registry": "workspace:*", + "ai": "^6.0.146", + "nestjs-pino": "^4.3.0", + "zod": "^3.25.76" + }, + "devDependencies": { + "@nestjs/testing": "^11.0.1", + "@types/node": "^25.5.0", + "@vitest/coverage-v8": "^2.1.9", + "typescript": "^5.7.3", + "unplugin-swc": "^1.5.9", + "vitest": "^2.1.9" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.1" + } +} \ No newline at end of file diff --git a/engine/ai/core/src/ai-engine.module.ts b/engine/ai/core/src/ai-engine.module.ts new file mode 100644 index 00000000..9d8af728 --- /dev/null +++ b/engine/ai/core/src/ai-engine.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PiecesModule, MetadataModule } from '@nexiom/piece-registry'; +import { OrchestratorService } from './services/orchestrator.service.js'; + +@Module({ + imports: [PiecesModule, MetadataModule], + providers: [OrchestratorService], + exports: [OrchestratorService], +}) +export class AiEngineModule {} diff --git a/apps/api/src/modules/ai/_constants/prompts.ts b/engine/ai/core/src/constants/prompts.ts similarity index 100% rename from apps/api/src/modules/ai/_constants/prompts.ts rename to engine/ai/core/src/constants/prompts.ts diff --git a/engine/ai/core/src/index.ts b/engine/ai/core/src/index.ts new file mode 100644 index 00000000..600cda14 --- /dev/null +++ b/engine/ai/core/src/index.ts @@ -0,0 +1,3 @@ +export * from './ai-engine.module.js'; +export * from './services/orchestrator.service.js'; +export * from './types/chat-request.types.js'; diff --git a/apps/api/src/modules/ai/_services/orchestrator.service.spec.ts b/engine/ai/core/src/services/orchestrator.service.spec.ts similarity index 98% rename from apps/api/src/modules/ai/_services/orchestrator.service.spec.ts rename to engine/ai/core/src/services/orchestrator.service.spec.ts index 47ebb693..5d8842d2 100644 --- a/apps/api/src/modules/ai/_services/orchestrator.service.spec.ts +++ b/engine/ai/core/src/services/orchestrator.service.spec.ts @@ -5,8 +5,7 @@ import { OrchestratorService } from './orchestrator.service.js'; import { PinoLogger } from 'nestjs-pino'; import { DATABASE_CONNECTION } from '@nexiom/database'; import { TokenManagerService } from '@nexiom/credentials'; -import { PieceRegistryService } from '@nexiom/engine'; -import { MetadataDiscoveryService } from '../../metadata/metadata-discovery.service.js'; +import { PieceRegistryService, MetadataDiscoveryService } from '@nexiom/piece-registry'; describe('OrchestratorService - Enterprise Hardened', () => { let service: OrchestratorService; @@ -228,7 +227,7 @@ describe('OrchestratorService - Enterprise Hardened', () => { expect(result.data.status).toBe('PAID'); expect(mockActionRun).toHaveBeenCalledWith({ auth: { token: '123' }, - propsValue: { id: 'inv-123', confirmed: true }, + propsValue: { id: 'inv-123' }, }); }); diff --git a/apps/api/src/modules/ai/_services/orchestrator.service.ts b/engine/ai/core/src/services/orchestrator.service.ts similarity index 89% rename from apps/api/src/modules/ai/_services/orchestrator.service.ts rename to engine/ai/core/src/services/orchestrator.service.ts index a2af0ea3..0867a3d0 100644 --- a/apps/api/src/modules/ai/_services/orchestrator.service.ts +++ b/engine/ai/core/src/services/orchestrator.service.ts @@ -5,6 +5,7 @@ import { dynamicTool, stepCountIs, convertToModelMessages, + zodSchema, type UIMessage, } from 'ai'; import { z } from 'zod'; @@ -19,17 +20,29 @@ import { import type { DrizzleDb } from '@nexiom/database'; import { TokenManagerService } from '@nexiom/credentials'; import type { OAuthCredentialBlob } from '@nexiom/credentials'; -import { PieceRegistryService } from '@nexiom/engine'; -import { MetadataDiscoveryService } from '../../metadata/metadata-discovery.service.js'; +import { PieceRegistryService, MetadataDiscoveryService } from '@nexiom/piece-registry'; import type { Piece } from '@nexiom/piece-framework'; import { AI_COPILOT_SYSTEM_PROMPT, AI_COPILOT_TOOL_INSTRUCTIONS, -} from '../_constants/prompts.js'; +} from '../constants/prompts.js'; /** Maximum parallel related object fetch calls to prevent overwhelming external APIs */ const MAX_PARALLEL_RELATED_CALLS = 5; +/** + * Wraps zodSchema() with an explicit `any` boundary. + * zodSchema recursively resolves Zod's complex generic tree, causing TS2589 + * ("type instantiation excessively deep") with Zod v3.25+ inside dynamicTool generics. + * This wrapper breaks the chain — dynamicTool validates the schema at runtime anyway. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function toAISchema(schema: z.ZodTypeAny): any { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TS2589 — Zod v3.25 generic depth overflows tsc; runtime is correct + return zodSchema(schema); +} + /** Casts OAuthCredentialBlob to the generic Record the Piece interface expects. */ function toCredentialsRecord( credentials: OAuthCredentialBlob, @@ -184,6 +197,19 @@ export class OrchestratorService { const toolName = `${conn.appName}_${conn.id}_getEntityWithRelations`; + const hydratorInputSchema = z.object({ + objectType: z + .string() + .describe( + `The primary entity type (e.g. 'Load', 'Invoice', 'Account', 'Order')`, + ), + filters: z + .record(z.string(), z.string()) + .describe( + `Properties to search by. E.g. {"Name": "211032"} or {"DocNumber": "123"}. Prefer intuitive visual identifiers.`, + ), + }); + tools[toolName] = dynamicTool({ description: [ `Fetches a ${piece.displayName} entity AND ALL its related sub-entities`, @@ -191,23 +217,14 @@ export class OrchestratorService { `in a SINGLE call. Uses connection ${conn.id}.`, `Use this for ANY "give me details of X" or "show me X with everything" query.`, ].join(' '), - inputSchema: z.object({ - objectType: z - .string() - .describe( - `The primary entity type (e.g. 'Load', 'Invoice', 'Account', 'Order')`, - ), - filters: z - .record(z.string(), z.string()) - .describe( - `Properties to search by. E.g. {"Name": "211032"} or {"DocNumber": "123"}. Prefer intuitive visual identifiers.`, - ), - }), - execute: async (args: Record) => { - const objectType = args.objectType as string; - const filters = args.filters as Record; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + inputSchema: toAISchema(hydratorInputSchema), + execute: async (input: unknown) => { + const { objectType, filters } = input as z.infer; + const objectTypeName: string = objectType; + const filterMap: Record = filters; this.logger.info( - { traceId, app: conn.appName, objectType, filters }, + { traceId, app: conn.appName, objectType: objectTypeName, filters: filterMap }, 'Hydrating entity with all relations', ); @@ -225,10 +242,10 @@ export class OrchestratorService { 'Step 1 complete: Metadata retrieved', ); - const tName = objectType.toLowerCase(); - let resolvedObjectName = objectType; + const tName = objectTypeName.toLowerCase(); + let resolvedObjectName: string = objectTypeName; const match = - objects.find((o) => o.label === objectType) || + objects.find((o) => o.label === objectTypeName) || objects.find( (o) => o.name.toLowerCase() === tName || @@ -239,12 +256,12 @@ export class OrchestratorService { resolvedObjectName = match.name; } else { this.logger.warn( - { traceId, objectType }, + { traceId, objectType: objectTypeName }, 'AI passed object type not found in Metadata Dictionary.', ); return { connectionName: `connection-${conn.id}`, - error: `Object type "${objectType}" not found in metadata dictionary. Please use a valid object type from the available metadata.`, + error: `Object type "${objectTypeName}" not found in metadata dictionary. Please use a valid object type from the available metadata.`, }; } @@ -263,7 +280,7 @@ export class OrchestratorService { try { const results = await piece.executeFind( resolvedObjectName, - filters, + filterMap, creds, ); if (Array.isArray(results) && results.length > 0) { @@ -455,13 +472,17 @@ export class OrchestratorService { .optional() .describe('User confirmation required before executing this action'); + const actionExecutorInputSchema = z.object(shape); + tools[toolName] = dynamicTool({ description: [ action.description || `Execute: ${action.displayName}`, `(via connection ${conn.id})`, ].join(' '), - inputSchema: z.object(shape), - execute: async (args) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + inputSchema: toAISchema(actionExecutorInputSchema), + execute: async (input: unknown) => { + const args = input as z.infer; this.logger.info( { traceId, tool: toolName, connectionId: conn.id }, 'Executing action tool', @@ -488,10 +509,13 @@ export class OrchestratorService { }; } + // Remove orchestration-only 'confirmed' field before passing to action layer + const { confirmed: _confirmed, ...sanitizedArgs } = argsWithConfirm; + try { const result = (await action.run({ auth: creds, - propsValue: args as Record, + propsValue: sanitizedArgs, })) as unknown; return { success: true, @@ -617,4 +641,4 @@ export class OrchestratorService { return Object.keys(pruned).length > 0 ? pruned : undefined; } -} +} \ No newline at end of file diff --git a/apps/api/src/modules/ai/_types/chat-request.types.ts b/engine/ai/core/src/types/chat-request.types.ts similarity index 100% rename from apps/api/src/modules/ai/_types/chat-request.types.ts rename to engine/ai/core/src/types/chat-request.types.ts diff --git a/engine/ai/core/tsconfig.json b/engine/ai/core/tsconfig.json new file mode 100644 index 00000000..ad392bba --- /dev/null +++ b/engine/ai/core/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "types": ["vitest/globals"] + }, + "include": ["src/**/*"], + "exclude": ["src/**/*.spec.ts"] +} diff --git a/engine/ai/core/vitest.config.ts b/engine/ai/core/vitest.config.ts new file mode 100644 index 00000000..a08db844 --- /dev/null +++ b/engine/ai/core/vitest.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vitest/config'; +import swc from 'unplugin-swc'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + include: ['src/**/*.spec.ts'], + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html'], + include: ['src/**/*.ts'], + exclude: ['src/**/*.spec.ts', 'src/**/index.ts'], + }, + }, + plugins: [swc.vite({ module: { type: 'es6' } })], +}); diff --git a/engine/application/README.md b/engine/sync/application/README.md similarity index 100% rename from engine/application/README.md rename to engine/sync/application/README.md diff --git a/engine/application/mapping/package.json b/engine/sync/application/mapping/package.json similarity index 100% rename from engine/application/mapping/package.json rename to engine/sync/application/mapping/package.json diff --git a/engine/application/mapping/src/config-applicator.ts b/engine/sync/application/mapping/src/config-applicator.ts similarity index 100% rename from engine/application/mapping/src/config-applicator.ts rename to engine/sync/application/mapping/src/config-applicator.ts diff --git a/engine/application/mapping/src/index.ts b/engine/sync/application/mapping/src/index.ts similarity index 100% rename from engine/application/mapping/src/index.ts rename to engine/sync/application/mapping/src/index.ts diff --git a/engine/application/mapping/src/jsonata-extensions.ts b/engine/sync/application/mapping/src/jsonata-extensions.ts similarity index 100% rename from engine/application/mapping/src/jsonata-extensions.ts rename to engine/sync/application/mapping/src/jsonata-extensions.ts diff --git a/engine/application/mapping/src/mapping-engine.spec.ts b/engine/sync/application/mapping/src/mapping-engine.spec.ts similarity index 100% rename from engine/application/mapping/src/mapping-engine.spec.ts rename to engine/sync/application/mapping/src/mapping-engine.spec.ts diff --git a/engine/application/mapping/src/mapping-engine.ts b/engine/sync/application/mapping/src/mapping-engine.ts similarity index 100% rename from engine/application/mapping/src/mapping-engine.ts rename to engine/sync/application/mapping/src/mapping-engine.ts diff --git a/engine/application/mapping/src/mapping.types.ts b/engine/sync/application/mapping/src/mapping.types.ts similarity index 100% rename from engine/application/mapping/src/mapping.types.ts rename to engine/sync/application/mapping/src/mapping.types.ts diff --git a/engine/application/mapping/tsconfig.json b/engine/sync/application/mapping/tsconfig.json similarity index 84% rename from engine/application/mapping/tsconfig.json rename to engine/sync/application/mapping/tsconfig.json index fb50fb99..f8b81fa1 100644 --- a/engine/application/mapping/tsconfig.json +++ b/engine/sync/application/mapping/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "rootDir": "./src", "outDir": "./dist", diff --git a/engine/application/mapping/vitest.config.ts b/engine/sync/application/mapping/vitest.config.ts similarity index 100% rename from engine/application/mapping/vitest.config.ts rename to engine/sync/application/mapping/vitest.config.ts diff --git a/engine/platform/README.md b/engine/sync/platform/README.md similarity index 100% rename from engine/platform/README.md rename to engine/sync/platform/README.md diff --git a/engine/platform/core/package.json b/engine/sync/platform/core/package.json similarity index 100% rename from engine/platform/core/package.json rename to engine/sync/platform/core/package.json diff --git a/engine/platform/core/src/evaluator.ts b/engine/sync/platform/core/src/evaluator.ts similarity index 100% rename from engine/platform/core/src/evaluator.ts rename to engine/sync/platform/core/src/evaluator.ts diff --git a/engine/platform/core/src/hydrator.ts b/engine/sync/platform/core/src/hydrator.ts similarity index 100% rename from engine/platform/core/src/hydrator.ts rename to engine/sync/platform/core/src/hydrator.ts diff --git a/engine/platform/core/src/index.ts b/engine/sync/platform/core/src/index.ts similarity index 71% rename from engine/platform/core/src/index.ts rename to engine/sync/platform/core/src/index.ts index c292da91..bd3729be 100644 --- a/engine/platform/core/src/index.ts +++ b/engine/sync/platform/core/src/index.ts @@ -3,9 +3,7 @@ export { CursorManagerService, DEFAULT_CURSOR_CHECKPOINT_INTERVAL, } from './state/cursor-manager.service.js'; -export * from './pieces/pieces.module.js'; -export * from './pieces/piece-registry.service.js'; -export * from './pieces/piece-loader.service.js'; + export * from './storage-resolver/storage-resolver.module.js'; export * from './storage-resolver/storage-resolver.service.js'; diff --git a/engine/platform/core/src/state/cursor-manager.service.spec.ts b/engine/sync/platform/core/src/state/cursor-manager.service.spec.ts similarity index 100% rename from engine/platform/core/src/state/cursor-manager.service.spec.ts rename to engine/sync/platform/core/src/state/cursor-manager.service.spec.ts diff --git a/engine/platform/core/src/state/cursor-manager.service.ts b/engine/sync/platform/core/src/state/cursor-manager.service.ts similarity index 100% rename from engine/platform/core/src/state/cursor-manager.service.ts rename to engine/sync/platform/core/src/state/cursor-manager.service.ts diff --git a/engine/platform/core/src/state/cursor-manager.types.ts b/engine/sync/platform/core/src/state/cursor-manager.types.ts similarity index 100% rename from engine/platform/core/src/state/cursor-manager.types.ts rename to engine/sync/platform/core/src/state/cursor-manager.types.ts diff --git a/engine/platform/core/src/storage-resolver/storage-resolver.module.ts b/engine/sync/platform/core/src/storage-resolver/storage-resolver.module.ts similarity index 100% rename from engine/platform/core/src/storage-resolver/storage-resolver.module.ts rename to engine/sync/platform/core/src/storage-resolver/storage-resolver.module.ts diff --git a/engine/platform/core/src/storage-resolver/storage-resolver.service.spec.ts b/engine/sync/platform/core/src/storage-resolver/storage-resolver.service.spec.ts similarity index 100% rename from engine/platform/core/src/storage-resolver/storage-resolver.service.spec.ts rename to engine/sync/platform/core/src/storage-resolver/storage-resolver.service.spec.ts diff --git a/engine/platform/core/src/storage-resolver/storage-resolver.service.ts b/engine/sync/platform/core/src/storage-resolver/storage-resolver.service.ts similarity index 100% rename from engine/platform/core/src/storage-resolver/storage-resolver.service.ts rename to engine/sync/platform/core/src/storage-resolver/storage-resolver.service.ts diff --git a/engine/platform/core/tsconfig.json b/engine/sync/platform/core/tsconfig.json similarity index 83% rename from engine/platform/core/tsconfig.json rename to engine/sync/platform/core/tsconfig.json index 122b457c..b06e2d9c 100644 --- a/engine/platform/core/tsconfig.json +++ b/engine/sync/platform/core/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "rootDir": "./src", "outDir": "./dist", diff --git a/engine/platform/core/vitest.config.ts b/engine/sync/platform/core/vitest.config.ts similarity index 100% rename from engine/platform/core/vitest.config.ts rename to engine/sync/platform/core/vitest.config.ts diff --git a/engine/platform/credentials/package.json b/packages/credentials/package.json similarity index 100% rename from engine/platform/credentials/package.json rename to packages/credentials/package.json diff --git a/engine/platform/credentials/src/crypto/encryption.interface.ts b/packages/credentials/src/crypto/encryption.interface.ts similarity index 100% rename from engine/platform/credentials/src/crypto/encryption.interface.ts rename to packages/credentials/src/crypto/encryption.interface.ts diff --git a/engine/platform/credentials/src/crypto/encryption.service.spec.ts b/packages/credentials/src/crypto/encryption.service.spec.ts similarity index 100% rename from engine/platform/credentials/src/crypto/encryption.service.spec.ts rename to packages/credentials/src/crypto/encryption.service.spec.ts diff --git a/engine/platform/credentials/src/crypto/encryption.service.ts b/packages/credentials/src/crypto/encryption.service.ts similarity index 100% rename from engine/platform/credentials/src/crypto/encryption.service.ts rename to packages/credentials/src/crypto/encryption.service.ts diff --git a/engine/platform/credentials/src/http-client/host-http-client.spec.ts b/packages/credentials/src/http-client/host-http-client.spec.ts similarity index 100% rename from engine/platform/credentials/src/http-client/host-http-client.spec.ts rename to packages/credentials/src/http-client/host-http-client.spec.ts diff --git a/engine/platform/credentials/src/http-client/host-http-client.ts b/packages/credentials/src/http-client/host-http-client.ts similarity index 100% rename from engine/platform/credentials/src/http-client/host-http-client.ts rename to packages/credentials/src/http-client/host-http-client.ts diff --git a/engine/platform/credentials/src/index.ts b/packages/credentials/src/index.ts similarity index 100% rename from engine/platform/credentials/src/index.ts rename to packages/credentials/src/index.ts diff --git a/engine/platform/credentials/src/oauth/token-manager.service.ts b/packages/credentials/src/oauth/token-manager.service.ts similarity index 100% rename from engine/platform/credentials/src/oauth/token-manager.service.ts rename to packages/credentials/src/oauth/token-manager.service.ts diff --git a/engine/platform/credentials/tsconfig.json b/packages/credentials/tsconfig.json similarity index 79% rename from engine/platform/credentials/tsconfig.json rename to packages/credentials/tsconfig.json index 1efec046..33cc445e 100644 --- a/engine/platform/credentials/tsconfig.json +++ b/packages/credentials/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../tsconfig.base.json", "compilerOptions": { "rootDir": "./src", "outDir": "./dist", @@ -15,7 +15,7 @@ ], "references": [ { - "path": "../../../packages/database" + "path": "../../packages/database" } ] } \ No newline at end of file diff --git a/engine/platform/credentials/tsconfig.spec.json b/packages/credentials/tsconfig.spec.json similarity index 100% rename from engine/platform/credentials/tsconfig.spec.json rename to packages/credentials/tsconfig.spec.json diff --git a/engine/platform/credentials/vitest.config.ts b/packages/credentials/vitest.config.ts similarity index 100% rename from engine/platform/credentials/vitest.config.ts rename to packages/credentials/vitest.config.ts diff --git a/packages/infra-adapters/eslint.config.mjs b/packages/infra/eslint.config.mjs similarity index 100% rename from packages/infra-adapters/eslint.config.mjs rename to packages/infra/eslint.config.mjs diff --git a/packages/infra-adapters/package.json b/packages/infra/package.json similarity index 96% rename from packages/infra-adapters/package.json rename to packages/infra/package.json index 79d2c4c6..397b6f5f 100644 --- a/packages/infra-adapters/package.json +++ b/packages/infra/package.json @@ -1,5 +1,5 @@ { - "name": "@nexiom/infra-adapters", + "name": "@nexiom/infra", "version": "0.0.1", "type": "module", "private": true, diff --git a/packages/infra-adapters/src/adapters/aws-kms.adapter.ts b/packages/infra/src/adapters/aws-kms.adapter.ts similarity index 100% rename from packages/infra-adapters/src/adapters/aws-kms.adapter.ts rename to packages/infra/src/adapters/aws-kms.adapter.ts diff --git a/packages/infra-adapters/src/adapters/local-crypto.adapter.ts b/packages/infra/src/adapters/local-crypto.adapter.ts similarity index 100% rename from packages/infra-adapters/src/adapters/local-crypto.adapter.ts rename to packages/infra/src/adapters/local-crypto.adapter.ts diff --git a/packages/infra-adapters/src/aws-kms.adapter.spec.ts b/packages/infra/src/aws-kms.adapter.spec.ts similarity index 100% rename from packages/infra-adapters/src/aws-kms.adapter.spec.ts rename to packages/infra/src/aws-kms.adapter.spec.ts diff --git a/packages/infra-adapters/src/constants.ts b/packages/infra/src/constants.ts similarity index 100% rename from packages/infra-adapters/src/constants.ts rename to packages/infra/src/constants.ts diff --git a/packages/infra-adapters/src/encryption.module.spec.ts b/packages/infra/src/encryption.module.spec.ts similarity index 100% rename from packages/infra-adapters/src/encryption.module.spec.ts rename to packages/infra/src/encryption.module.spec.ts diff --git a/packages/infra-adapters/src/encryption.module.ts b/packages/infra/src/encryption.module.ts similarity index 100% rename from packages/infra-adapters/src/encryption.module.ts rename to packages/infra/src/encryption.module.ts diff --git a/packages/infra-adapters/src/index.ts b/packages/infra/src/index.ts similarity index 100% rename from packages/infra-adapters/src/index.ts rename to packages/infra/src/index.ts diff --git a/packages/infra-adapters/src/interfaces/encryption-service.interface.ts b/packages/infra/src/interfaces/encryption-service.interface.ts similarity index 100% rename from packages/infra-adapters/src/interfaces/encryption-service.interface.ts rename to packages/infra/src/interfaces/encryption-service.interface.ts diff --git a/packages/infra-adapters/src/local-crypto.adapter.spec.ts b/packages/infra/src/local-crypto.adapter.spec.ts similarity index 100% rename from packages/infra-adapters/src/local-crypto.adapter.spec.ts rename to packages/infra/src/local-crypto.adapter.spec.ts diff --git a/packages/infra-adapters/tsconfig.json b/packages/infra/tsconfig.json similarity index 100% rename from packages/infra-adapters/tsconfig.json rename to packages/infra/tsconfig.json diff --git a/packages/infra-adapters/vitest.config.ts b/packages/infra/vitest.config.ts similarity index 100% rename from packages/infra-adapters/vitest.config.ts rename to packages/infra/vitest.config.ts diff --git a/packages/pieces/registry/package.json b/packages/pieces/registry/package.json new file mode 100644 index 00000000..b90fe254 --- /dev/null +++ b/packages/pieces/registry/package.json @@ -0,0 +1,33 @@ +{ + "name": "@nexiom/piece-registry", + "version": "1.0.0", + "type": "module", + "private": true, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "scripts": { + "build": "tsc" + }, + "dependencies": { + "@nestjs/common": "^11.0.1", + "@nestjs/config": "^4.0.2", + "@nexiom/piece-framework": "workspace:*", + "@nexiom/database": "workspace:*", + "@nexiom/credentials": "workspace:*", + "@nexiom/cache": "workspace:*", + "drizzle-orm": "^0.45.1" + }, + "devDependencies": { + "typescript": "^5.7.3" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.1" + } +} diff --git a/packages/pieces/registry/src/index.ts b/packages/pieces/registry/src/index.ts new file mode 100644 index 00000000..a9a5a786 --- /dev/null +++ b/packages/pieces/registry/src/index.ts @@ -0,0 +1,5 @@ +export * from './pieces/piece-registry.service.js'; +export * from './pieces/piece-loader.service.js'; +export * from './pieces/pieces.module.js'; +export * from './metadata/metadata-discovery.service.js'; +export * from './metadata/metadata.module.js'; diff --git a/apps/api/src/modules/metadata/metadata-discovery.service.spec.ts b/packages/pieces/registry/src/metadata/metadata-discovery.service.spec.ts similarity index 99% rename from apps/api/src/modules/metadata/metadata-discovery.service.spec.ts rename to packages/pieces/registry/src/metadata/metadata-discovery.service.spec.ts index ff922773..5e206ed9 100644 --- a/apps/api/src/modules/metadata/metadata-discovery.service.spec.ts +++ b/packages/pieces/registry/src/metadata/metadata-discovery.service.spec.ts @@ -9,7 +9,7 @@ import { TokenManagerService } from '@nexiom/credentials'; import { MetadataDiscoveryService } from './metadata-discovery.service.js'; import { DATABASE_CONNECTION } from '@nexiom/database'; import { REDIS_CLIENT } from '@nexiom/cache'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '../pieces/piece-registry.service.js'; const CONN_ID = 'conn-uuid-1'; const ORG_ID = 'org-uuid-1'; diff --git a/apps/api/src/modules/metadata/metadata-discovery.service.ts b/packages/pieces/registry/src/metadata/metadata-discovery.service.ts similarity index 99% rename from apps/api/src/modules/metadata/metadata-discovery.service.ts rename to packages/pieces/registry/src/metadata/metadata-discovery.service.ts index a8c425c3..7eed3325 100644 --- a/apps/api/src/modules/metadata/metadata-discovery.service.ts +++ b/packages/pieces/registry/src/metadata/metadata-discovery.service.ts @@ -17,7 +17,7 @@ import { } from '@nexiom/database'; import { REDIS_CLIENT, type Redis } from '@nexiom/cache'; import { TokenManagerService } from '@nexiom/credentials'; -import { PieceRegistryService } from '@nexiom/engine'; +import { PieceRegistryService } from '../pieces/piece-registry.service.js'; import type { OAuthCredentialBlob } from '@nexiom/credentials'; import type { ObjectDescriptor, diff --git a/packages/pieces/registry/src/metadata/metadata.module.ts b/packages/pieces/registry/src/metadata/metadata.module.ts new file mode 100644 index 00000000..7cee45f6 --- /dev/null +++ b/packages/pieces/registry/src/metadata/metadata.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PiecesModule } from '../pieces/pieces.module.js'; +import { MetadataDiscoveryService } from './metadata-discovery.service.js'; + +@Module({ + imports: [PiecesModule], + providers: [MetadataDiscoveryService], + exports: [MetadataDiscoveryService], +}) +export class MetadataModule {} diff --git a/engine/platform/core/src/pieces/piece-loader.service.ts b/packages/pieces/registry/src/pieces/piece-loader.service.ts similarity index 100% rename from engine/platform/core/src/pieces/piece-loader.service.ts rename to packages/pieces/registry/src/pieces/piece-loader.service.ts diff --git a/engine/platform/core/src/pieces/piece-registry.service.spec.ts b/packages/pieces/registry/src/pieces/piece-registry.service.spec.ts similarity index 100% rename from engine/platform/core/src/pieces/piece-registry.service.spec.ts rename to packages/pieces/registry/src/pieces/piece-registry.service.spec.ts diff --git a/engine/platform/core/src/pieces/piece-registry.service.ts b/packages/pieces/registry/src/pieces/piece-registry.service.ts similarity index 100% rename from engine/platform/core/src/pieces/piece-registry.service.ts rename to packages/pieces/registry/src/pieces/piece-registry.service.ts diff --git a/engine/platform/core/src/pieces/pieces.module.ts b/packages/pieces/registry/src/pieces/pieces.module.ts similarity index 100% rename from engine/platform/core/src/pieces/pieces.module.ts rename to packages/pieces/registry/src/pieces/pieces.module.ts diff --git a/packages/pieces/registry/tsconfig.json b/packages/pieces/registry/tsconfig.json new file mode 100644 index 00000000..0849f29c --- /dev/null +++ b/packages/pieces/registry/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "lib": [ + "ES2022" + ], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "dist", + "node_modules" + ] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19704581..5a3b2f55 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,6 +69,9 @@ importers: '@nestjs/schedule': specifier: ^6.1.1 version: 6.1.1(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11) + '@nexiom/ai-engine': + specifier: workspace:* + version: link:../../engine/ai/core '@nexiom/auth': specifier: workspace:* version: link:../../packages/auth @@ -77,7 +80,7 @@ importers: version: link:../../packages/cache '@nexiom/credentials': specifier: workspace:* - version: link:../../engine/platform/credentials + version: link:../../packages/credentials '@nexiom/database': specifier: workspace:* version: link:../../packages/database @@ -86,7 +89,7 @@ importers: version: link:../../packages/dbmanager '@nexiom/engine': specifier: workspace:* - version: link:../../engine/platform/core + version: link:../../engine/sync/platform/core '@nexiom/identity': specifier: workspace:* version: link:../../packages/identity @@ -96,6 +99,9 @@ importers: '@nexiom/piece-quickbooks': specifier: workspace:* version: link:../../packages/pieces/quickbooks + '@nexiom/piece-registry': + specifier: workspace:* + version: link:../../packages/pieces/registry '@nexiom/piece-salesforce': specifier: workspace:* version: link:../../packages/pieces/salesforce @@ -530,7 +536,7 @@ importers: version: link:../../packages/cache '@nexiom/credentials': specifier: workspace:* - version: link:../../engine/platform/credentials + version: link:../../packages/credentials '@nexiom/database': specifier: workspace:* version: link:../../packages/database @@ -539,7 +545,7 @@ importers: version: link:../../packages/dbmanager '@nexiom/engine': specifier: workspace:* - version: link:../../engine/platform/core + version: link:../../engine/sync/platform/core '@nexiom/identity': specifier: workspace:* version: link:../../packages/identity @@ -549,6 +555,9 @@ importers: '@nexiom/piece-quickbooks': specifier: workspace:* version: link:../../packages/pieces/quickbooks + '@nexiom/piece-registry': + specifier: workspace:* + version: link:../../packages/pieces/registry '@nexiom/piece-salesforce': specifier: workspace:* version: link:../../packages/pieces/salesforce @@ -710,7 +719,56 @@ importers: specifier: ^3.0.0 version: 3.0.0 - engine/application/mapping: + engine/ai/core: + dependencies: + '@ai-sdk/google': + specifier: ^3.0.58 + version: 3.0.58(zod@3.25.76) + '@nestjs/common': + specifier: ^11.0.1 + version: 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nexiom/credentials': + specifier: workspace:* + version: link:../../../packages/credentials + '@nexiom/database': + specifier: workspace:* + version: link:../../../packages/database + '@nexiom/piece-framework': + specifier: workspace:* + version: link:../../../packages/pieces/framework + '@nexiom/piece-registry': + specifier: workspace:* + version: link:../../../packages/pieces/registry + ai: + specifier: ^6.0.146 + version: 6.0.146(zod@3.25.76) + nestjs-pino: + specifier: ^4.3.0 + version: 4.6.1(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(pino-http@11.0.0)(pino@10.3.1)(rxjs@7.8.2) + zod: + specifier: ^3.25.76 + version: 3.25.76 + devDependencies: + '@nestjs/testing': + specifier: ^11.0.1 + version: 11.1.11(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.11)(@nestjs/platform-express@11.1.11) + '@types/node': + specifier: ^25.5.0 + version: 25.5.0 + '@vitest/coverage-v8': + specifier: ^2.1.9 + version: 2.1.9(vitest@2.1.9(@types/node@25.5.0)(happy-dom@20.1.0)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)) + typescript: + specifier: ^5.7.3 + version: 5.9.3 + unplugin-swc: + specifier: ^1.5.9 + version: 1.5.9(@swc/core@1.15.11)(rollup@4.55.1) + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@25.5.0)(happy-dom@20.1.0)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1) + + engine/sync/application/mapping: dependencies: jsonata: specifier: ^2.1.0 @@ -726,17 +784,17 @@ importers: specifier: ^2.1.9 version: 2.1.9(@types/node@25.5.0)(happy-dom@20.1.0)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1) - engine/platform/core: + engine/sync/platform/core: dependencies: '@nexiom/credentials': specifier: workspace:* - version: link:../credentials + version: link:../../../../packages/credentials '@nexiom/database': specifier: workspace:* - version: link:../../../packages/database + version: link:../../../../packages/database '@nexiom/piece-framework': specifier: workspace:* - version: link:../../../packages/pieces/framework + version: link:../../../../packages/pieces/framework ai: specifier: ^6.0.146 version: 6.0.146(zod@4.3.5) @@ -760,34 +818,6 @@ importers: specifier: ^2.1.9 version: 2.1.9(@types/node@25.5.0)(happy-dom@20.1.0)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1) - engine/platform/credentials: - dependencies: - '@nexiom/database': - specifier: workspace:* - version: link:../../../packages/database - '@nexiom/piece-framework': - specifier: workspace:* - version: link:../../../packages/pieces/framework - drizzle-orm: - specifier: ^0.45.1 - version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(kysely@0.28.9)(pg@8.16.3) - ioredis: - specifier: ^5.3.2 - version: 5.10.0 - devDependencies: - '@nestjs/common': - specifier: ^11.0.1 - version: 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@vitest/coverage-v8': - specifier: ^4.0.18 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) - typescript: - specifier: ^5.7.3 - version: 5.9.3 - vitest: - specifier: ^4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - packages/auth: dependencies: '@nexiom/identity': @@ -865,6 +895,34 @@ importers: specifier: ^5.7.3 version: 5.9.3 + packages/credentials: + dependencies: + '@nexiom/database': + specifier: workspace:* + version: link:../database + '@nexiom/piece-framework': + specifier: workspace:* + version: link:../pieces/framework + drizzle-orm: + specifier: ^0.45.1 + version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(kysely@0.28.9)(pg@8.16.3) + ioredis: + specifier: ^5.3.2 + version: 5.10.0 + devDependencies: + '@nestjs/common': + specifier: ^11.0.1 + version: 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@vitest/coverage-v8': + specifier: ^4.0.18 + version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vitest: + specifier: ^4.0.18 + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + packages/database: dependencies: '@nestjs/common': @@ -1009,7 +1067,7 @@ importers: specifier: ^2.1.9 version: 2.1.9(@types/node@22.19.3)(happy-dom@20.1.0)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1) - packages/infra-adapters: + packages/infra: dependencies: '@aws-sdk/client-kms': specifier: ^3.750.0 @@ -1096,7 +1154,7 @@ importers: dependencies: '@nexiom/credentials': specifier: workspace:* - version: link:../../../engine/platform/credentials + version: link:../../credentials '@nexiom/piece-framework': specifier: workspace:* version: link:../framework @@ -1108,11 +1166,39 @@ importers: specifier: ^4.0.18 version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + packages/pieces/registry: + dependencies: + '@nestjs/common': + specifier: ^11.0.1 + version: 11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/config': + specifier: ^4.0.2 + version: 4.0.2(@nestjs/common@11.1.11(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + '@nexiom/cache': + specifier: workspace:* + version: link:../../cache + '@nexiom/credentials': + specifier: workspace:* + version: link:../../credentials + '@nexiom/database': + specifier: workspace:* + version: link:../../database + '@nexiom/piece-framework': + specifier: workspace:* + version: link:../framework + drizzle-orm: + specifier: ^0.45.1 + version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(kysely@0.28.9)(pg@8.16.3) + devDependencies: + typescript: + specifier: ^5.7.3 + version: 5.9.3 + packages/pieces/salesforce: dependencies: '@nexiom/credentials': specifier: workspace:* - version: link:../../../engine/platform/credentials + version: link:../../credentials '@nexiom/piece-framework': specifier: workspace:* version: link:../framework @@ -9175,10 +9261,6 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - sax@1.4.4: - resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} - engines: {node: '>=11.0.0'} - sax@1.6.0: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} @@ -10139,8 +10221,8 @@ packages: terser: optional: true - vite@7.3.1: - resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + vite@7.3.2: + resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -10468,6 +10550,9 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.3.5: resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} @@ -10480,6 +10565,13 @@ snapshots: '@adobe/css-tools@4.4.4': {} + '@ai-sdk/gateway@3.0.88(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.22(zod@3.25.76) + '@vercel/oidc': 3.1.0 + zod: 3.25.76 + '@ai-sdk/gateway@3.0.88(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.8 @@ -10487,12 +10579,25 @@ snapshots: '@vercel/oidc': 3.1.0 zod: 4.3.5 + '@ai-sdk/google@3.0.58(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.22(zod@3.25.76) + zod: 3.25.76 + '@ai-sdk/google@3.0.58(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.8 '@ai-sdk/provider-utils': 4.0.22(zod@4.3.5) zod: 4.3.5 + '@ai-sdk/provider-utils@4.0.22(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.6 + zod: 3.25.76 + '@ai-sdk/provider-utils@4.0.22(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.8 @@ -15319,23 +15424,23 @@ snapshots: msw: 2.12.10(@types/node@25.5.0)(typescript@5.9.3) vite: 5.4.21(@types/node@25.5.0)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1) - '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(vite@7.3.1(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(vite@7.3.2(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.10(@types/node@22.19.3)(typescript@5.9.3) - vite: 7.3.1(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(vite@7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.10(@types/node@25.5.0)(typescript@5.9.3) - vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) '@vitest/pretty-format@2.1.9': dependencies: @@ -15604,6 +15709,14 @@ snapshots: agent-base@7.1.4: {} + ai@6.0.146(zod@3.25.76): + dependencies: + '@ai-sdk/gateway': 3.0.88(zod@3.25.76) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.22(zod@3.25.76) + '@opentelemetry/api': 1.9.0 + zod: 3.25.76 + ai@6.0.146(zod@4.3.5): dependencies: '@ai-sdk/gateway': 3.0.88(zod@4.3.5) @@ -18812,7 +18925,7 @@ snapshots: needle@3.3.1: dependencies: iconv-lite: 0.6.3 - sax: 1.4.4 + sax: 1.6.0 optional: true negotiator@0.6.3: {} @@ -20108,9 +20221,6 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.6 - sax@1.4.4: - optional: true - sax@1.6.0: {} saxes@6.0.0: @@ -21291,7 +21401,7 @@ snapshots: sass-embedded: 1.97.3 terser: 5.44.1 - vite@7.3.1(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.2(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -21311,7 +21421,7 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vite@7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -21482,7 +21592,7 @@ snapshots: vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@22.19.3)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(vite@7.3.1(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@22.19.3)(typescript@5.9.3))(vite@7.3.2(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -21499,7 +21609,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@22.19.3)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 @@ -21522,7 +21632,7 @@ snapshots: vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(happy-dom@20.1.0)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@2.0.1))(less@4.5.1)(lightningcss@1.30.2)(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@25.5.0)(typescript@5.9.3))(vite@7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -21539,7 +21649,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vite: 7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 @@ -21825,6 +21935,8 @@ snapshots: dependencies: zod: 4.3.5 + zod@3.25.76: {} + zod@4.3.5: {} zwitch@2.0.4: {} \ No newline at end of file diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9359a1d6..41242414 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,6 +1,7 @@ packages: - 'apps/*' - 'packages/*' - - 'engine/platform/*' - - 'engine/application/*' + - 'engine/sync/platform/*' + - 'engine/sync/application/*' + - 'engine/ai/*' - 'packages/pieces/*'