poker_updateSource
Update radiation source parameters including position, nuclide inventory, geometry, and division settings for existing sources in radiation management systems.
Instructions
既存放射線源のパラメータを更新します
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cutoff_rate | No | 新しいカットオフレート | |
| division | No | 新しい線源分割パラメータ(完全なoneOf制約付き) | |
| geometry | No | 新しい線源形状パラメータ(完全なoneOf制約付き) | |
| inventory | No | 新しい核種インベントリ | |
| name | Yes | 更新対象線源名 | |
| position | No | 新しい線源位置 (x y z形式) |
Implementation Reference
- src/mcp/handlers/sourceHandlers.js:34-59 (handler)The MCP handler function for 'poker_updateSource'. Validates input with validateUpdateSourceRequest, calls taskManager.updateSource with name and updates, returns success message or specific error for non-existent source.async updateSource(args) { try { validateUpdateSourceRequest(args); const { name, ...updates } = args; const result = await taskManager.updateSource(name, updates); return { success: true, message: result }; } catch (error) { logger.error('updateSourceハンドラーエラー', { args, error: error.message }); // マニフェスト仕様のupdate専用エラーコード処理 if (error.code === -32079) { return { success: false, error: error.message, details: { errorCode: error.code, suggestion: 'proposeSourceメソッドを使用してください', missingObject: args.name, objectType: '線源' } }; } throw error; } },
- src/mcp/tools/sourceTools.js:436-711 (schema)Tool registration object defining name, description, and comprehensive inputSchema with strict validation (patterns, enums, oneOf for geometry/division matching source types).{ name: 'poker_updateSource', description: '既存放射線源のパラメータを更新します', inputSchema: { type: 'object', properties: { name: { type: 'string', description: '更新対象線源名' }, position: { type: 'string', description: '新しい線源位置 (x y z形式)' }, inventory: { type: 'array', description: '新しい核種インベントリ', items: { type: 'object', properties: { nuclide: { type: 'string', description: '核種名(連結形式、例: Cs137, Co60)', pattern: '^[A-Z][a-z]{0,2}[0-9]{1,3}[a-z]?$' }, radioactivity: { type: 'number', description: '放射能 (Bq)', minimum: 0.001, maximum: 1e15 } }, required: ['nuclide', 'radioactivity'] }, minItems: 1 }, geometry: { type: 'object', description: '新しい線源形状パラメータ(完全なoneOf制約付き)', oneOf: [ { title: 'BOX線源形状', properties: { vertex: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, edge_1: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, edge_2: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, edge_3: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, transform: { type: 'string', description: '適用する変換名', pattern: '^[a-zA-Z0-9_]+$', maxLength: 50 } }, required: ['vertex', 'edge_1', 'edge_2', 'edge_3'], additionalProperties: false }, { title: 'RPP線源形状', properties: { min: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, max: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, transform: { type: 'string', description: '適用する変換名', pattern: '^[a-zA-Z0-9_]+$', maxLength: 50 } }, required: ['min', 'max'], additionalProperties: false }, { title: 'SPH線源形状', properties: { center: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, radius: { type: 'number', minimum: 0.001, maximum: 10000 }, transform: { type: 'string', description: '適用する変換名', pattern: '^[a-zA-Z0-9_]+$', maxLength: 50 } }, required: ['center', 'radius'], additionalProperties: false }, { title: 'RCC線源形状', properties: { bottom_center: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, height_vector: { type: 'string', pattern: '^-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?\\s+-?\\d+(\\.\\d+)?$' }, radius: { type: 'number', minimum: 0.001, maximum: 10000 }, transform: { type: 'string', description: '適用する変換名', pattern: '^[a-zA-Z0-9_]+$', maxLength: 50 } }, required: ['bottom_center', 'height_vector', 'radius'], additionalProperties: false } ] }, division: { type: 'object', description: '新しい線源分割パラメータ(完全なoneOf制約付き)', oneOf: [ { title: 'BOX線源分割', properties: { edge_1: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, edge_2: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, edge_3: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false } }, required: ['edge_1', 'edge_2', 'edge_3'], additionalProperties: false }, { title: 'SPH線源分割', properties: { r: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, theta: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, phi: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false } }, required: ['r', 'theta', 'phi'], additionalProperties: false }, { title: 'RCC線源分割', properties: { r: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, phi: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false }, z: { type: 'object', properties: { type: { enum: ['UNIFORM', 'GAUSS_FIRST', 'GAUSS_LAST', 'GAUSS_BOTH', 'GAUSS_CENTER'] }, number: { type: 'integer', minimum: 2, maximum: 1000 }, min: { type: 'number', minimum: 0.0, maximum: 1.0 }, max: { type: 'number', minimum: 0.0, maximum: 1.0 } }, required: ['type', 'number'], additionalProperties: false } }, required: ['r', 'phi', 'z'], additionalProperties: false } ] }, cutoff_rate: { type: 'number', description: '新しいカットオフレート', minimum: 0, maximum: 1 } }, required: ['name'] } },
- Core business logic in TaskManager for source update: full validation/normalization/checks, adds 'updateSource' pending change to be applied later.async updateSource(name, updates) { try { if (!name) throw new ValidationError('線源のnameは必須です', 'name', name); // 既存更新専用チェック - マニフェスト仕様準拠 this.validateUpdatePrerequisites('source', name, (n) => this.findSourceByName(n)); // 既存線源の存在確認(詳細情報取得のため) const existingSource = this.findSourceByName(name); // 更新内容のバリデーションと正規化 const normalizedUpdates = { ...updates }; // POINT線源のposition更新 if (normalizedUpdates.position) { this.validatePosition(normalizedUpdates.position); normalizedUpdates.position = this.normalizeCoordinates(normalizedUpdates.position); } // インベントリの更新 if (normalizedUpdates.inventory) { NuclideValidator.validateInventory(normalizedUpdates.inventory); } // geometryの更新 if (normalizedUpdates.geometry) { // 既存Sourceのtypeを取得してgeometry検証 const sourceType = existingSource.type; SourceValidator.validateSourceGeometry(sourceType, normalizedUpdates.geometry); normalizedUpdates.geometry = this.normalizeGeometryData(normalizedUpdates.geometry); // Transform参照チェック if (normalizedUpdates.geometry.transform) { TransformValidator.validateContextTransformReference( normalizedUpdates.geometry.transform, this.data, 'source', name ); } } // divisionの更新 if (normalizedUpdates.division) { const sourceType = existingSource.type; SourceValidator.validateSourceDivision(sourceType, normalizedUpdates.division); } // cutoff_rateの更新 if (normalizedUpdates.cutoff_rate !== undefined) { SourceValidator.validateCutoffRate(normalizedUpdates.cutoff_rate); } // typeの変更は禁止(物理的整合性のため) if (normalizedUpdates.type && normalizedUpdates.type !== existingSource.type) { throw new ValidationError('線源のtypeは変更できません', 'type', normalizedUpdates.type); } // 更新後の構造最適化分析 const mergedSource = { ...existingSource, ...normalizedUpdates }; const optimization = SourceValidator.analyzeSrcStructureOptimization(mergedSource); if (optimization.suggestions.length > 0) { logger.info('Source更新後の最適化提案', { name, suggestions: optimization.suggestions }); } await this.dataManager.addPendingChange({ action: 'updateSource', data: { name, ...normalizedUpdates } }); logger.info('線源更新を提案しました', { name, updates: normalizedUpdates }); return `提案: 線源 ${name} の更新を保留しました`; } catch (error) { logger.error('線源更新エラー', { name, error: error.message }); throw error; }
- src/mcp/server.js:43-56 (registration)MCP server request handler for tool calls. Maps 'poker_updateSource' to handlers['updateSource'] via replace('poker_', ''), executes handler with args.this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; logger.info(`MCP Tool実行: ${name}`, { args }); // ハンドラー名をツール名から生成(プレフィックス除去) const handlerName = name.replace('poker_', ''); const handler = this.handlers[handlerName]; if (!handler) { throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`); } return await safeExecute(async () => handler(args), { tool: name })();
- Input validation function specifically for updateSource request, enforcing schema constraints.export function validateUpdateSourceRequest(args) { if (!args.name || typeof args.name !== 'string') { throw new ValidationError('線源名は必須です', 'name', args.name); } // 更新可能なフィールドのみチェック const allowedFields = ['name', 'position', 'inventory', 'cutoff_rate']; const providedFields = Object.keys(args); const invalidFields = providedFields.filter(field => !allowedFields.includes(field)); if (invalidFields.length > 0) { throw new ValidationError(`更新不可なフィールド: ${invalidFields.join(', ')}`, 'fields', invalidFields); } if (args.inventory && !Array.isArray(args.inventory)) { throw new ValidationError('インベントリは配列で指定してください', 'inventory', args.inventory); } if (args.cutoff_rate !== undefined && (typeof args.cutoff_rate !== 'number' || args.cutoff_rate < 0)) { throw new ValidationError('cutoff_rateは0以上の数値で指定してください', 'cutoff_rate', args.cutoff_rate); } } export function validateDeleteSourceRequest(args) { if (!args.name || typeof args.name !== 'string') {