| |
| |
| |
| |
| |
| |
|
|
| import { |
| ModelVendor, |
| SymbolicPrimitive, |
| GrammarStyle, |
| SymbolicOperation, |
| VendorImplementation, |
| SYMBOLIC_RUNTIME_SCHEMA |
| } from './universal-symbolics-runtime'; |
|
|
| import { SymbolicsRegistry } from './universal-symbolics-registry'; |
|
|
| |
| |
| |
| export interface HarmonizationOptions { |
| preserveStructure?: boolean; |
| adaptToCapabilities?: boolean; |
| includeComments?: boolean; |
| embedTraceability?: boolean; |
| formatOutput?: boolean; |
| handleResidue?: boolean; |
| fallbackBehavior?: 'omit' | 'emulate' | 'comment'; |
| } |
|
|
| |
| |
| |
| export interface HarmonizationResult { |
| transformed: string; |
| originalVendor: ModelVendor; |
| targetVendor: ModelVendor; |
| operations: { |
| original: SymbolicPrimitive; |
| target: SymbolicPrimitive | null; |
| success: boolean; |
| message?: string; |
| }[]; |
| residue: { |
| pattern: string; |
| position: number; |
| possiblePrimitive?: SymbolicPrimitive; |
| }[]; |
| metrics: { |
| totalOperations: number; |
| successfulOperations: number; |
| unsupportedOperations: number; |
| adaptedOperations: number; |
| }; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export class SymbolicHarmonizer { |
| private registry: SymbolicsRegistry; |
| |
| constructor(registry?: SymbolicsRegistry) { |
| this.registry = registry || new SymbolicsRegistry(); |
| } |
| |
| |
| |
| |
| public harmonize( |
| content: string, |
| sourceVendor: ModelVendor, |
| targetVendor: ModelVendor, |
| options: HarmonizationOptions = {} |
| ): HarmonizationResult { |
| |
| const opts: Required<HarmonizationOptions> = { |
| preserveStructure: options.preserveStructure !== undefined ? options.preserveStructure : true, |
| adaptToCapabilities: options.adaptToCapabilities !== undefined ? options.adaptToCapabilities : true, |
| includeComments: options.includeComments !== undefined ? options.includeComments : false, |
| embedTraceability: options.embedTraceability !== undefined ? options.embedTraceability : false, |
| formatOutput: options.formatOutput !== undefined ? options.formatOutput : true, |
| handleResidue: options.handleResidue !== undefined ? options.handleResidue : true, |
| fallbackBehavior: options.fallbackBehavior || 'emulate' |
| }; |
| |
| |
| const result: HarmonizationResult = { |
| transformed: '', |
| originalVendor: sourceVendor, |
| targetVendor: targetVendor, |
| operations: [], |
| residue: [], |
| metrics: { |
| totalOperations: 0, |
| successfulOperations: 0, |
| unsupportedOperations: 0, |
| adaptedOperations: 0 |
| } |
| }; |
| |
| |
| if (sourceVendor === targetVendor) { |
| result.transformed = content; |
| return result; |
| } |
| |
| |
| if (opts.handleResidue) { |
| result.residue = this.registry.findSymbolicResidue(content, sourceVendor); |
| |
| |
| if (result.residue.length > 0) { |
| content = this.registry.repairSymbolicResidue(content, sourceVendor); |
| } |
| } |
| |
| |
| const extractedOperations = this.registry.extractAllSymbolicOperations(content, sourceVendor); |
| result.metrics.totalOperations = extractedOperations.length; |
| |
| |
| const operationPositions = this.mapOperationPositions(content, sourceVendor); |
| |
| |
| const operationResults: { primitive: SymbolicPrimitive, params: any, success: boolean, message?: string, transformed?: string }[] = []; |
| |
| for (const { primitive, params } of extractedOperations) { |
| const operationResult = this.transformOperation(primitive, params, sourceVendor, targetVendor, opts); |
| operationResults.push({ |
| primitive, |
| params, |
| success: operationResult.success, |
| message: operationResult.message, |
| transformed: operationResult.transformed |
| }); |
| |
| |
| if (operationResult.success) { |
| result.metrics.successfulOperations++; |
| |
| if (operationResult.adapted) { |
| result.metrics.adaptedOperations++; |
| } |
| } else { |
| result.metrics.unsupportedOperations++; |
| } |
| |
| |
| result.operations.push({ |
| original: primitive, |
| target: operationResult.targetPrimitive, |
| success: operationResult.success, |
| message: operationResult.message |
| }); |
| } |
| |
| |
| result.transformed = this.generateTransformedContent( |
| content, |
| operationPositions, |
| operationResults, |
| sourceVendor, |
| targetVendor, |
| opts |
| ); |
| |
| |
| if (opts.formatOutput) { |
| result.transformed = this.formatOutput(result.transformed, targetVendor); |
| } |
| |
| return result; |
| } |
| |
| |
| |
| |
| private transformOperation( |
| primitive: SymbolicPrimitive, |
| params: any, |
| sourceVendor: ModelVendor, |
| targetVendor: ModelVendor, |
| options: Required<HarmonizationOptions> |
| ): { |
| success: boolean; |
| message?: string; |
| transformed?: string; |
| targetPrimitive: SymbolicPrimitive | null; |
| adapted: boolean; |
| } { |
| |
| const targetSupport = this.registry.vendorSupports(targetVendor, primitive); |
| |
| |
| let targetPrimitive = primitive; |
| let adapted = false; |
| |
| if (!targetSupport && options.adaptToCapabilities) { |
| const alternativePrimitive = this.findAlternativePrimitive(primitive, targetVendor); |
| |
| if (alternativePrimitive) { |
| targetPrimitive = alternativePrimitive; |
| adapted = true; |
| } |
| } |
| |
| |
| const finalSupport = this.registry.vendorSupports(targetVendor, targetPrimitive); |
| |
| if (!finalSupport) { |
| |
| switch (options.fallbackBehavior) { |
| case 'omit': |
| return { |
| success: false, |
| message: `Operation ${primitive} not supported by ${targetVendor} and omitted`, |
| targetPrimitive: null, |
| adapted: false |
| }; |
| |
| case 'comment': |
| return { |
| success: false, |
| message: `Operation ${primitive} not supported by ${targetVendor}`, |
| transformed: this.generateCommentForUnsupported(primitive, params, sourceVendor, targetVendor), |
| targetPrimitive: null, |
| adapted: false |
| }; |
| |
| case 'emulate': |
| |
| const emulatedTransformation = this.emulateOperation(primitive, params, sourceVendor, targetVendor); |
| |
| if (emulatedTransformation) { |
| return { |
| success: true, |
| message: `Operation ${primitive} emulated for ${targetVendor}`, |
| transformed: emulatedTransformation, |
| targetPrimitive: targetPrimitive, |
| adapted: true |
| }; |
| } |
| |
| |
| return { |
| success: false, |
| message: `Operation ${primitive} not supported by ${targetVendor} and cannot be emulated`, |
| transformed: this.generateCommentForUnsupported(primitive, params, sourceVendor, targetVendor), |
| targetPrimitive: null, |
| adapted: false |
| }; |
| } |
| } |
| |
| |
| const implementation = this.registry.getVendorImplementation(targetPrimitive, targetVendor); |
| if (!implementation) { |
| return { |
| success: false, |
| message: `Could not find implementation for ${targetPrimitive} in ${targetVendor}`, |
| targetPrimitive: null, |
| adapted: false |
| }; |
| } |
| |
| |
| let adaptedParams = params; |
| if (adapted) { |
| adaptedParams = this.adaptParameters(params, primitive, targetPrimitive); |
| } |
| |
| |
| const transformed = this.generateTransformation(targetPrimitive, adaptedParams, implementation); |
| |
| |
| let finalTransformed = transformed; |
| |
| if (options.includeComments) { |
| finalTransformed = this.addComments(transformed, primitive, sourceVendor, targetPrimitive, targetVendor, adapted); |
| } |
| |
| if (options.embedTraceability) { |
| finalTransformed = this.embedTraceability(finalTransformed, primitive, sourceVendor, targetVendor); |
| } |
| |
| return { |
| success: true, |
| message: adapted ? `Operation ${primitive} adapted to ${targetPrimitive} for ${targetVendor}` : undefined, |
| transformed: finalTransformed, |
| targetPrimitive: targetPrimitive, |
| adapted: adapted |
| }; |
| } |
| |
| |
| |
| |
| private mapOperationPositions(content: string, vendor: ModelVendor): Map<SymbolicPrimitive, number[]> { |
| const positions = new Map<SymbolicPrimitive, number[]>(); |
| |
| |
| for (const primitive of Object.values(SymbolicPrimitive)) { |
| positions.set(primitive, []); |
| } |
| |
| |
| switch (vendor) { |
| case ModelVendor.ANTHROPIC: |
| |
| for (const primitive of Object.values(SymbolicPrimitive)) { |
| const implementation = this.registry.getVendorImplementation(primitive, vendor); |
| if (!implementation || implementation.style !== GrammarStyle.XML_TAGS) continue; |
| |
| if (implementation.prefix && implementation.suffix) { |
| const regex = new RegExp(`${escapeRegExp(implementation.prefix)}[\\s\\S]*?${escapeRegExp(implementation.suffix)}`, 'g'); |
| let match; |
| const primitivePositions = positions.get(primitive) || []; |
| |
| while ((match = regex.exec(content)) !== null) { |
| primitivePositions.push(match.index); |
| } |
| |
| positions.set(primitive, primitivePositions); |
| } |
| } |
| break; |
| |
| case ModelVendor.QWEN: |
| case ModelVendor.OPENAI: |
| |
| for (const primitive of Object.values(SymbolicPrimitive)) { |
| const implementation = this.registry.getVendorImplementation(primitive, vendor); |
| if (!implementation || implementation.style !== GrammarStyle.SLASH_COMMANDS) continue; |
| |
| if (implementation.prefix) { |
| const regex = new RegExp(`${escapeRegExp(implementation.prefix)}\\s+[^\\n]*`, 'g'); |
| let match; |
| const primitivePositions = positions.get(primitive) || []; |
| |
| while ((match = regex.exec(content)) !== null) { |
| primitivePositions.push(match.index); |
| } |
| |
| positions.set(primitive, primitivePositions); |
| } |
| } |
| break; |
| |
| |
| } |
| |
| return positions; |
| } |
|
|