UNPKG

create-tensorify-plugin

Version:

Create Tensorify plugins with the latest SDK - Linear layer template

188 lines (173 loc) 5.4 kB
import { TensorifyPlugin, IPluginDefinition, PluginSettings, PluginCodeGenerationContext, NodeType, PluginCapability, HandleViewType, HandlePosition, EdgeType, NodeViewContainerType, IconType, SettingsUIType, SettingsDataType, PrevNodeAsInput, NextNodeAsOutput, } from "@tensorify.io/sdk"; /** * Linear Layer Plugin * * This plugin demonstrates the complete structure for a PyTorch linear layer. * Make sure you have the latest SDK linked: npm link @tensorify.io/sdk */ export default class LinearLayerPlugin extends TensorifyPlugin { constructor() { const definition: IPluginDefinition = { // Core Metadata (id, name, description, version, nodeType are derived from package.json) // nodeType is derived from package.json tensorify.pluginType field // Visual Configuration (comprehensive and required) visual: { containerType: NodeViewContainerType.DEFAULT, size: { width: 240, height: 140, }, padding: { inner: 16, outer: 8, extraPadding: false, }, styling: { borderRadius: 8, borderWidth: 2, shadowLevel: 1, theme: "auto", }, icons: { primary: { type: IconType.LUCIDE, value: "layers", }, secondary: [], showIconBackground: true, iconSize: "medium", }, labels: { title: "Linear Layer", dynamicLabelTemplate: "{inFeatures} → {outFeatures}", showLabels: true, labelPosition: "top", }, }, // Handle Configuration inputHandles: [PrevNodeAsInput], outputHandles: [NextNodeAsOutput], // Settings Configuration (UI components automatically generated) settingsFields: [ { key: "inFeatures", label: "Input Features", type: SettingsUIType.INPUT_NUMBER, dataType: SettingsDataType.NUMBER, defaultValue: 784, required: true, description: "Number of input features", validation: { min: 1, max: 100000, }, }, { key: "outFeatures", label: "Output Features", type: SettingsUIType.INPUT_NUMBER, dataType: SettingsDataType.NUMBER, defaultValue: 10, required: true, description: "Number of output features", validation: { min: 1, max: 100000, }, }, { key: "bias", label: "Use Bias", type: SettingsUIType.TOGGLE, dataType: SettingsDataType.BOOLEAN, defaultValue: true, required: false, description: "Whether to include bias parameters in the linear transformation", }, { key: "emitLinearVar", label: "Emit Linear Variable", type: SettingsUIType.TOGGLE, dataType: SettingsDataType.BOOLEAN, defaultValue: true, required: true, description: "Whether to emit the linear layer variable", }, ], // Plugin Metadata emits: { variables: [ { value: "linear_layer", switchKey: "settingsFields.emitLinearVar", isOnByDefault: true, type: NodeType.MODEL_LAYER, }, ], imports: [{ path: "torch", items: ["nn"] }], }, capabilities: [PluginCapability.CODE_GENERATION], requirements: { minSdkVersion: "1.0.0", dependencies: ["torch"], pythonPackages: ["torch"], }, }; super(definition); } public getTranslationCode( settings: PluginSettings, children?: any, context?: PluginCodeGenerationContext ): string { // Validate settings (returns PluginValidationResult with isValid boolean) const validation = this.validateSettings(settings); if (!validation.isValid) { throw new Error( `Settings validation failed: ${validation.errors.map((e) => e.message).join(", ")}` ); } // Extract settings values with defaults from CorePluginSettings const variableName = settings.variableName || "linear_layer"; const inFeatures = settings.inFeatures || 784; const outFeatures = settings.outFeatures || 10; const bias = settings.bias !== undefined ? settings.bias : true; // Additional validation for business logic if (typeof inFeatures !== "number" || inFeatures <= 0) { throw new Error("Input features must be a positive number"); } if (typeof outFeatures !== "number" || outFeatures <= 0) { throw new Error("Output features must be a positive number"); } // Safe context handling - getInput method available in TensorifyPlugin const inputData = context ? this.getInput(context, 0) : null; // Generate PyTorch Linear layer code return `# Linear Layer: ${inFeatures}${outFeatures} ${variableName} = torch.nn.Linear( in_features=${inFeatures}, out_features=${outFeatures}, bias=${bias ? "True" : "False"} ) # Initialize weights (optional) # torch.nn.init.xavier_uniform_(${variableName}.weight) # if ${variableName}.bias is not None: # torch.nn.init.zeros_(${variableName}.bias)`; } }