Skip to content
Draft
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
f4f7aa5
Fix typo in pipeline source node description
Tejeshyewale Apr 26, 2026
b22e844
docs: improve README clarity and deployment instructions
Tejeshyewale Apr 26, 2026
319fca1
Update README.md
Tejeshyewale Apr 26, 2026
7ce10e3
Create README.md
Tejeshyewale Apr 28, 2026
90fac4d
Create code.py
Tejeshyewale Apr 28, 2026
b0598a2
Create IGlobal.py
Tejeshyewale Apr 28, 2026
ca2b870
Create IInstance.py
Tejeshyewale Apr 28, 2026
5862bd8
Create services.json
Tejeshyewale Apr 28, 2026
b33eff4
Create requirements.txt
Tejeshyewale Apr 28, 2026
be13299
Update code.py
Tejeshyewale Apr 28, 2026
4d88f21
Add files via upload
Tejeshyewale Apr 28, 2026
48a784f
Rename IInstance.py to Instance.py
Tejeshyewale Apr 28, 2026
7e6963d
Update services.json
Tejeshyewale Apr 28, 2026
5952843
Update requirements.txt
Tejeshyewale Apr 28, 2026
c667348
Update README.md
Tejeshyewale Apr 28, 2026
12c00e2
Update requirements.txt
Tejeshyewale Apr 28, 2026
c587ada
Update code.py
Tejeshyewale Apr 28, 2026
bb482f0
Merge branch 'rocketride-org:develop' into develop
Tejeshyewale Apr 30, 2026
8e676e5
Fix PreProcessor structure and improve error handling
Tejeshyewale Apr 30, 2026
50a0bd4
Fix PreProcessor node structure and improve error handling
Tejeshyewale Apr 30, 2026
96cf781
Update IGlobal.py
Tejeshyewale Apr 30, 2026
92593be
Update Instance.py
Tejeshyewale Apr 30, 2026
fe1f418
Update code.py
Tejeshyewale Apr 30, 2026
89504f9
Update code.py
Tejeshyewale Apr 30, 2026
dc7f679
Update IGlobal.py
Tejeshyewale Apr 30, 2026
4c9d406
Update Instance.py
Tejeshyewale Apr 30, 2026
c39113d
Update services.json
Tejeshyewale Apr 30, 2026
47ad4f9
Update code.py
Tejeshyewale Apr 30, 2026
3e8e46b
Update IGlobal.py
Tejeshyewale Apr 30, 2026
5399865
Update Instance.py
Tejeshyewale Apr 30, 2026
43c725d
Update README.md
Tejeshyewale Apr 30, 2026
5602c71
Merge branch 'rocketride-org:develop' into develop
Tejeshyewale Apr 30, 2026
9eaba7e
Update IGlobal.py
Tejeshyewale May 1, 2026
efa13f6
Update Instance.py
Tejeshyewale May 1, 2026
66e54c3
Update code.py
Tejeshyewale May 1, 2026
cc8840e
Create __init__.py
Tejeshyewale May 1, 2026
1f33c2f
Update requirements.txt
Tejeshyewale May 1, 2026
4d29752
Update services.json
Tejeshyewale May 1, 2026
9ad5458
Rename Instance.py to IInstance.py
Tejeshyewale May 1, 2026
282a102
Delete nodes/src/nodes/ml_sklearn/model.pkl
Tejeshyewale May 1, 2026
718b5ce
Merge branch 'rocketride-org:develop' into develop
Tejeshyewale May 1, 2026
46d6428
Merge branch 'develop' into develop
kwit75 May 1, 2026
83abe32
Merge branch 'develop' into develop
kwit75 May 1, 2026
3d91916
Merge branch 'rocketride-org:develop' into develop
Tejeshyewale May 2, 2026
2f66442
Update code.py
Tejeshyewale May 5, 2026
7039924
Update IGlobal.py
Tejeshyewale May 5, 2026
dc2ab2f
Update IInstance.py
Tejeshyewale May 5, 2026
f36b225
Update services.json
Tejeshyewale May 5, 2026
0e4e36a
Update requirements.txt
Tejeshyewale May 5, 2026
c20d8ed
Merge branch 'rocketride-org:develop' into develop
Tejeshyewale May 5, 2026
5db3751
fix: ml_sklearn node - working inference, fixed services.json, added …
Tejeshyewale May 5, 2026
6c53920
fix: ruff linting issues in ml_sklearn node
Tejeshyewale May 5, 2026
40a4ee5
fix: ml_sklearn - forward input unchanged when no model loaded
Tejeshyewale May 5, 2026
d359ae4
fix: ml_sklearn - add writeText handler for text lane input
Tejeshyewale May 5, 2026
9671737
fix: ml_sklearn - ruff format fixes
Tejeshyewale May 5, 2026
57943c9
fix: ml_sklearn - writeText takes plain string not question object
Tejeshyewale May 6, 2026
26c9ac7
fix: ml_sklearn - use Answer object with getText/setText pattern
Tejeshyewale May 6, 2026
f61ba71
fix: ml_sklearn - use answers lane for input and test
Tejeshyewale May 6, 2026
6894f7b
fix: ml_sklearn - fix test case format to match guardrails pattern
Tejeshyewale May 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions nodes/src/nodes/ml_sklearn/IGlobal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# =============================================================================
# MIT License
# Copyright (c) 2026 RocketRide Contributors
# =============================================================================

# ------------------------------------------------------------------------------
# This class controls the data shared between all threads for the task
# ------------------------------------------------------------------------------
import os

from rocketlib import IGlobalBase, OPEN_MODE, warning
from ai.common.config import Config


class IGlobal(IGlobalBase):
"""Global state for the ml_sklearn node — holds the loaded sklearn model."""

preprocessor: object = None # The sklearn model/pipeline instance

def validateConfig(self):
"""Validate that scikit-learn and numpy are available."""
try:
from depends import depends

requirements = os.path.dirname(os.path.realpath(__file__)) + '/requirements.txt'
depends(requirements)
except Exception as e: # noqa: BLE001
warning(str(e))

def beginGlobal(self):
"""Load the sklearn model at runtime startup."""
if self.IEndpoint.endpoint.openMode == OPEN_MODE.CONFIG:
# Config mode: don't load the model, we'll only be called
# to configure the service definition.
pass
else:
from depends import depends

requirements = os.path.dirname(os.path.realpath(__file__)) + '/requirements.txt'
depends(requirements)

# Deferred import — only after deps are installed
from .code import PreProcessor

config = Config.getNodeConfig(self.glb.logicalType, self.glb.connConfig)
self.preprocessor = PreProcessor(config)

def endGlobal(self):
"""Release the sklearn model."""
self.preprocessor = None
45 changes: 45 additions & 0 deletions nodes/src/nodes/ml_sklearn/IInstance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# =============================================================================
# MIT License
# Copyright (c) 2026 RocketRide Contributors
# =============================================================================

# ------------------------------------------------------------------------------
# This class controls the data for each thread of the task
# ------------------------------------------------------------------------------
import copy

from rocketlib import IInstanceBase, Entry

from .IGlobal import IGlobal


class IInstance(IInstanceBase):
"""Per-thread instance for the ml_sklearn node."""

IGlobal: IGlobal

def open(self, obj: Entry):
"""Called before each new pipeline object — nothing to reset for this node."""
pass

def writeAnswers(self, question):
"""
Receive a question from upstream, run sklearn inference on its text,
and forward the result to the answers output lane.

The question is deep-copied to prevent mutation in fan-out pipelines.
"""
if self.IGlobal.preprocessor is None:
raise RuntimeError('sklearn PreProcessor not initialized')

question = copy.deepcopy(question)

# Get the text to process
text = question.text if hasattr(question, 'text') else str(question)

# Run inference
result = self.IGlobal.preprocessor.process(text)

# Write result back to the question object and forward downstream
question.text = result
self.instance.writeAnswers(question)
19 changes: 19 additions & 0 deletions nodes/src/nodes/ml_sklearn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ML Sklearn Prediction Node

This node performs predictions using a trained scikit-learn model.

## Input

- text (number as string)

## Output

- text (predicted value as string)

## Example
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Input:
250

Output:
3.5
4 changes: 4 additions & 0 deletions nodes/src/nodes/ml_sklearn/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .IGlobal import IGlobal
from .IInstance import IInstance

__all__ = ['IGlobal', 'IInstance']
47 changes: 47 additions & 0 deletions nodes/src/nodes/ml_sklearn/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# =============================================================================
# MIT License
# Copyright (c) 2026 RocketRide Contributors
# =============================================================================

# ------------------------------------------------------------------------------
# PreProcessor: sklearn-based text inference class
# All heavy imports are deferred — this file is imported only after
# depends() has installed requirements.txt in beginGlobal().
# ------------------------------------------------------------------------------


class PreProcessor:
"""Wraps a scikit-learn model/pipeline for text inference."""

def __init__(self, config: dict):
"""
Initialize the sklearn model.

In a real deployment, you'd load a pickled model from a path
specified in config. This stub returns text unchanged so the
node is CI-safe without a pre-trained model artifact.
"""
# Example: load a real model like this:
# import joblib
# model_path = config.get('model_path', '')
# self._model = joblib.load(model_path)
self._model = None # Replace with actual model loading

def process(self, text: str) -> str:
"""
Run sklearn inference on input text and return processed text.

Args:
text: The input string to process.

Returns:
The processed string. Currently passes through unchanged.
"""
if self._model is None:
# Pass-through when no model is loaded (safe for CI)
return text

# Example with a real model:
# prediction = self._model.predict([text])
# return str(prediction[0])
return text
2 changes: 2 additions & 0 deletions nodes/src/nodes/ml_sklearn/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
scikit-learn>=1.0.0,<2.0.0
numpy>=1.21.0,<3.0.0
52 changes: 52 additions & 0 deletions nodes/src/nodes/ml_sklearn/services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"ml_sklearn": {
"name": "ML sklearn",
"description": "Applies a trained scikit-learn model to process text through the pipeline.",
"icon": "python.svg",
"group": "preprocessor",
"color": "#f97316",
"runtime": "python",
"pipe": {
"lanes": {
"answers": {
"in": true,
"out": true
}
}
},
"preconfig": {
"default": {
"object": "default",
"properties": []
}
},
"profiles": {
"ml_sklearn.default": {
"object": "default",
"properties": []
}
},
"fields": [],
"shape": {
"inputs": [
{
"name": "answers",
"type": "answers"
}
],
"outputs": [
{
"name": "answers",
"type": "answers"
}
]
},
"test": {
"answers": [
{
"text": "hello world"
}
]
}
}
}
Loading