Skip to main content
Glama

Poker Task Management MCP

by Hirao-Y
EnhancedValidator.js15.4 kB
/** * 強化された検証機能 * マニフェスト enhanced_features.enhanced_validation に基づく実装 */ import { logger } from './logger.js'; class EnhancedValidator { constructor() { this.validationRules = new Map(); this.initializeValidationRules(); } /** * 検証ルールの初期化 */ initializeValidationRules() { // 物理整合性ルール this.validationRules.set('physics_consistency', [ this.validateMaterialDensity, this.validateSourceActivity, this.validateGeometryScale, this.validateDetectorPlacement ]); // 単位互換性ルール this.validationRules.set('units_compatibility', [ this.validateUnitConsistency, this.validateDimensionalAnalysis, this.validateCoordinateSystem ]); // 材料物性ルール this.validationRules.set('material_property', [ this.validateMaterialCombinations, this.validateDensityRanges, this.validateVoidMaterial ]); // CMB式検証ルール this.validationRules.set('cmb_expression', [ this.validateCMBSyntax, this.validateCMBReferences, this.validateCMBLogic ]); } /** * 包括的検証の実行 * @param {Object} data - YAMLデータ * @returns {Object} 検証結果 */ async performComprehensiveValidation(data) { try { logger.info('包括的検証を開始'); const validationResults = { overall: true, categories: {}, errors: [], warnings: [], recommendations: [] }; // 各カテゴリの検証実行 for (const [category, rules] of this.validationRules) { logger.info(`${category} カテゴリの検証中`); const categoryResult = await this.runCategoryValidation(category, rules, data); validationResults.categories[category] = categoryResult; // 全体結果の更新 if (!categoryResult.passed) { validationResults.overall = false; } validationResults.errors.push(...categoryResult.errors); validationResults.warnings.push(...categoryResult.warnings); validationResults.recommendations.push(...categoryResult.recommendations); } logger.info('包括的検証完了', { overall: validationResults.overall, errorCount: validationResults.errors.length, warningCount: validationResults.warnings.length }); return validationResults; } catch (error) { logger.error('包括的検証中にエラー', { error: error.message }); throw new Error(`検証エラー: ${error.message}`); } } /** * カテゴリ別検証の実行 * @param {string} category - カテゴリ名 * @param {Array} rules - 検証ルール配列 * @param {Object} data - データ * @returns {Object} カテゴリ検証結果 */ async runCategoryValidation(category, rules, data) { const result = { category, passed: true, errors: [], warnings: [], recommendations: [] }; for (const rule of rules) { try { const ruleResult = await rule.call(this, data); if (ruleResult.errors && ruleResult.errors.length > 0) { result.passed = false; result.errors.push(...ruleResult.errors); } if (ruleResult.warnings) { result.warnings.push(...ruleResult.warnings); } if (ruleResult.recommendations) { result.recommendations.push(...ruleResult.recommendations); } } catch (ruleError) { logger.error(`検証ルール実行エラー: ${rule.name}`, { error: ruleError.message }); result.errors.push({ type: 'validation_error', rule: rule.name, message: `検証ルールエラー: ${ruleError.message}` }); result.passed = false; } } return result; } // ========== 物理整合性検証 ========== /** * 材料密度の物理的妥当性チェック */ async validateMaterialDensity(data) { const result = { errors: [], warnings: [], recommendations: [] }; if (!data.zone) return result; const densityRanges = { 'LEAD': { min: 10.0, max: 12.0, typical: 11.34 }, 'CONCRETE': { min: 1.8, max: 2.8, typical: 2.3 }, 'Iron': { min: 7.0, max: 8.5, typical: 7.87 }, 'Aluminum': { min: 2.5, max: 2.8, typical: 2.70 }, 'Copper': { min: 8.5, max: 9.2, typical: 8.96 }, 'Air': { min: 0.001, max: 0.002, typical: 0.00129 } }; for (const zone of data.zone) { if (zone.material === 'VOID') continue; const range = densityRanges[zone.material]; if (range && zone.density) { if (zone.density < range.min || zone.density > range.max) { result.errors.push({ type: 'density_out_of_range', material: zone.material, density: zone.density, expectedRange: `${range.min} - ${range.max}`, message: `${zone.material}の密度${zone.density}が物理的範囲外です` }); } // 推奨値との比較 const deviation = Math.abs(zone.density - range.typical) / range.typical; if (deviation > 0.1) { // 10%以上の偏差 result.warnings.push({ type: 'density_deviation', material: zone.material, density: zone.density, typical: range.typical, deviation: deviation, message: `${zone.material}の密度が標準値から${(deviation*100).toFixed(1)}%偏差しています` }); } } } return result; } /** * 線源放射能の妥当性チェック */ async validateSourceActivity(data) { const result = { errors: [], warnings: [], recommendations: [] }; if (!data.source) return result; for (const source of data.source) { if (!source.inventory) continue; for (const nuclide of source.inventory) { // 極端な放射能値のチェック if (nuclide.radioactivity > 1e15) { // 1 PBq超 result.warnings.push({ type: 'extremely_high_activity', source: source.name, nuclide: nuclide.nuclide, activity: nuclide.radioactivity, message: `${source.name}の${nuclide.nuclide}が極めて高い放射能です` }); } if (nuclide.radioactivity < 1e3) { // 1 kBq未満 result.recommendations.push({ type: 'low_activity', source: source.name, nuclide: nuclide.nuclide, activity: nuclide.radioactivity, message: `${source.name}の${nuclide.nuclide}の放射能が低く、計算精度に影響する可能性があります` }); } } } return result; } /** * 幾何学的スケールの妥当性チェック */ async validateGeometryScale(data) { const result = { errors: [], warnings: [], recommendations: [] }; if (!data.body) return result; for (const body of data.body) { const dimensions = this.extractDimensions(body); // 極端なサイズのチェック for (const dim of dimensions) { if (dim > 1e6) { // 1000m超 result.warnings.push({ type: 'extremely_large_dimension', body: body.name, dimension: dim, message: `${body.name}の寸法が極めて大きいです (${dim} cm)` }); } if (dim < 1e-3) { // 0.001cm未満 result.warnings.push({ type: 'extremely_small_dimension', body: body.name, dimension: dim, message: `${body.name}の寸法が極めて小さいです (${dim} cm)` }); } } } return result; } /** * 検出器配置の妥当性チェック */ async validateDetectorPlacement(data) { const result = { errors: [], warnings: [], recommendations: [] }; if (!data.detector || !data.source) return result; for (const detector of data.detector) { const detPos = this.parseCoordinates(detector.origin); // 線源との距離チェック for (const source of data.source) { let sourcePos; if (source.position) { sourcePos = this.parseCoordinates(source.position); } else if (source.geometry && source.geometry.center) { sourcePos = this.parseCoordinates(source.geometry.center); } else { continue; } const distance = this.calculateDistance(detPos, sourcePos); if (distance < 1.0) { // 1cm未満 result.errors.push({ type: 'detector_too_close', detector: detector.name, source: source.name, distance: distance, message: `検出器${detector.name}が線源${source.name}に近すぎます` }); } if (distance > 1e5) { // 1km超 result.warnings.push({ type: 'detector_very_far', detector: detector.name, source: source.name, distance: distance, message: `検出器${detector.name}が線源${source.name}から非常に遠いです` }); } } } return result; } // ========== 単位互換性検証 ========== /** * 単位の一貫性チェック */ async validateUnitConsistency(data) { const result = { errors: [], warnings: [], recommendations: [] }; if (!data.unit) { result.errors.push({ type: 'missing_unit_section', message: '単位セクションが存在しません' }); return result; } // 必須単位の存在チェック const requiredUnits = ['length', 'angle', 'density', 'radioactivity']; for (const unit of requiredUnits) { if (!data.unit[unit]) { result.errors.push({ type: 'missing_required_unit', unit: unit, message: `必須単位 ${unit} が定義されていません` }); } } return result; } /** * 次元解析チェック */ async validateDimensionalAnalysis(data) { const result = { errors: [], warnings: [], recommendations: [] }; // 実装は簡略化 // 実際には各パラメータの次元の整合性をチェック return result; } /** * 座標系の一貫性チェック */ async validateCoordinateSystem(data) { const result = { errors: [], warnings: [], recommendations: [] }; // 座標値の単位一貫性チェック if (data.unit && data.unit.length) { const lengthUnit = data.unit.length; // 実装は簡略化 result.recommendations.push({ type: 'coordinate_system_info', lengthUnit: lengthUnit, message: `座標系の長さ単位: ${lengthUnit}` }); } return result; } // ========== ヘルパーメソッド ========== /** * 立体の寸法抽出 */ extractDimensions(body) { const dimensions = []; switch (body.type) { case 'SPH': dimensions.push(body.radius * 2); break; case 'RPP': const min = this.parseCoordinates(body.min); const max = this.parseCoordinates(body.max); for (let i = 0; i < 3; i++) { dimensions.push(Math.abs(max[i] - min[i])); } break; case 'RCC': dimensions.push(body.radius * 2); const height = this.parseCoordinates(body.height_vector); dimensions.push(Math.sqrt(height[0]**2 + height[1]**2 + height[2]**2)); break; } return dimensions; } /** * 座標解析 */ parseCoordinates(coordStr) { if (typeof coordStr === 'string') { return coordStr.split(/\s+/).map(Number); } return [0, 0, 0]; } /** * 距離計算 */ calculateDistance(pos1, pos2) { return Math.sqrt( (pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2 + (pos1[2] - pos2[2])**2 ); } // ========== CMB式検証(簡略版) ========== async validateCMBSyntax(data) { return { errors: [], warnings: [], recommendations: [] }; } async validateCMBReferences(data) { return { errors: [], warnings: [], recommendations: [] }; } async validateCMBLogic(data) { return { errors: [], warnings: [], recommendations: [] }; } async validateMaterialCombinations(data) { return { errors: [], warnings: [], recommendations: [] }; } async validateDensityRanges(data) { return { errors: [], warnings: [], recommendations: [] }; } async validateVoidMaterial(data) { return { errors: [], warnings: [], recommendations: [] }; } } export default EnhancedValidator;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Hirao-Y/poker_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server