Skip to content

[Hackathon] feat: Custom Operator Builder — Create Reusable Operators from Code#5108

Open
EmilySun621 wants to merge 2 commits into
apache:mainfrom
EmilySun621:hackathon/custom-operators
Open

[Hackathon] feat: Custom Operator Builder — Create Reusable Operators from Code#5108
EmilySun621 wants to merge 2 commits into
apache:mainfrom
EmilySun621:hackathon/custom-operators

Conversation

@EmilySun621
Copy link
Copy Markdown

@EmilySun621 EmilySun621 commented May 16, 2026

[Hackathon] feat: Custom Operator Builder — Create Reusable Operators from Code

The Story

Dr. Sarah's lab has a set of Python functions they use in every project — a BMI calculator, an outlier remover, a custom normalization method specific to their biomedical data. Every time they start a new workflow, someone has to open a Python UDF operator and re-type (or copy-paste) the same code. If someone improves the function, the other workflows don't get the update. There's no library, no reuse, no sharing.

What if they could save their code as a real operator — one that appears in the operator panel, ready to drag and drop, just like the built-in ones?

What We Built

A Custom Operator Builder that lets users create reusable operators from Python code. Write once, use everywhere.

My Operators Page

New sidebar entry under "Your Work" → "My Operators":

  • Grid of saved custom operators, each showing icon, name, description, category
  • "+ Create Operator" button to build a new one
  • Edit, duplicate, delete existing operators

Full-Page Operator Editor

Split-screen editor like a real IDE:

Left panel (40%) — Configuration:

  • Name, description, icon picker (10 preset icons)
  • Category (default "My Operators", or create custom categories)
  • Input ports — define how many inputs and their types
  • Output ports — define outputs
  • Configurable properties — add parameters (string/number/boolean/select) that users can set per-instance, accessible in code via self.args['property_name']
  • "Make public" toggle for community sharing

Right panel (60%) — Code Editor:

  • Full Monaco editor with Python syntax highlighting
  • Pre-filled template with pytexera boilerplate
  • "Test Run" button for syntax validation
  • Same editor experience as Texera's built-in Python UDF

Drag & Drop in Workflow Editor

Once saved, custom operators appear in the operator panel (left side of workflow editor) under a "My Operators" category:

  • Shows alongside built-in operators
  • Drag onto canvas → creates a Python UDF node pre-filled with the saved code, custom display name, and configured ports
  • Works exactly like any built-in operator — connect, configure, run

How It Works Under the Hood

Custom operators don't modify Texera's operator registry or engine. They're a smart wrapper around Python UDF:

  • Dragging a custom operator creates a standard PythonUDFV2 node
  • The saved code is injected into the operator's code field
  • Custom properties are rendered as a PROPS = {...} dictionary prepended to the code
  • Ports are mapped to the UDF's dynamic port configuration
  • The customDisplayName shows the operator's name instead of "Python UDF"

This means zero engine changes, full compatibility with existing execution infrastructure.

Demo

  1. Open "My Operators" → "+ Create Operator"
  2. Name: "BMI Calculator", icon: 📊
  3. Configure 1 input port, 1 output port
  4. Write code:
    df['BMI'] = df['weight'] / (df['height'] / 100) ** 2
    yield df
  5. Save → operator card appears in My Operators page
  6. Open a workflow → left panel shows "My Operators" category
  7. Drag "BMI Calculator" onto canvas → Python UDF node appears with code pre-filled
  8. Connect to data source and run
Screenshot 2026-05-16 at 11 19 16 AM Screenshot 2026-05-16 at 11 19 30 AM Screenshot 2026-05-16 at 11 19 41 AM

Files Changed

New Components

  • dashboard/component/user/user-operator/user-operator.component.* — My Operators list/grid page
  • dashboard/component/user/user-operator/user-operator-editor.component.* — Full-page editor with Monaco
  • workspace/component/left-panel/operator-menu/custom-operator-label/custom-operator-label.component.* — Draggable label in operator panel

New Services

  • dashboard/service/user/custom-operator/custom-operator.service.ts — CRUD with localStorage persistence
  • dashboard/service/user/custom-operator/custom-operator-factory.service.ts — Builds PythonUDFV2 predicate from saved config

New Types

  • dashboard/type/custom-operator.interface.ts — CustomOperator, ports, properties, code template

Modified (additive only)

  • app-routing.module.ts — 3 new routes (list, create, edit)
  • dashboard.component.html/ts — "My Operators" sidebar link
  • operator-menu.component.* — "My Operators" collapse panel in workflow editor
  • drag-drop.service.tsdragStartedCustom() method for pre-built predicates

Testing

  • Angular typecheck: clean ✅
  • Create operator: save to localStorage ✅
  • Operator appears in panel: ✅
  • Drag to canvas: creates PythonUDFV2 with pre-filled code ✅
  • Edit/delete: ✅

Emily Sun and others added 2 commits May 15, 2026 21:55
This bundles the feature work that built up on this branch:

- Custom agents: dashboard CRUD page and editor dialog (48px icon tile,
  chip-style guardrails, model selector). Each custom agent now carries a
  LiteLLM model_name (Opus 4.7 / Haiku 4.5) that is passed through to the
  agent-service so different agents can use different models.

- Conversation history is scoped per (workflowId, agentId): switching
  agent or workflow yields a different conversation list. localStorage
  key: texera.workflowConversations.v1.{workflowId}.{agentId}.

- Time machine: workflow snapshot list, revert, and agent-tagged
  checkpoints. New workflow-history-tool in agent-service backs the
  "undo my last change" flow; amber gains a WorkflowSnapshotResource;
  sql/updates/23.sql adds the snapshot table.

- Operator-aware custom-agent prompts: the system prompt now injects the
  full operator catalog with a "prefer built-in operators over Python
  UDFs" rule, sourced from WorkflowSystemMetadata at request time.

- LiteLLM: added the claude-opus-4.7 entry alongside claude-haiku-4.5
  and gpt-5-mini in bin/litellm-config.yaml.

- Agent panel rewritten around the (conversation list / chat) two-view
  model with subscription-managed list reloads and per-step persistence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a "My Operators" section under Your Work where users can author
Python operators by writing UDF code, configuring ports/properties,
and saving them as draggable items in the workflow editor. Each saved
operator wraps a PythonUDFV2 node pre-filled with the saved code and
ports — no engine or operator-registry changes required.

- Data model + localStorage CRUD (custom-operator.{interface,service})
- "My Operators" list page + full-page editor with Monaco code editor,
  port/property builder, and a Test Run that validates UDF shape
- Operator panel surfaces a "My Operators" collapse at the top of the
  workflow editor; dragging a custom operator builds a PythonUDFV2
  predicate via CustomOperatorFactoryService and reuses the existing
  DragDropService flow via a new dragStartedCustom() entry point
- Custom properties get rendered as a PROPS dict prepended to the saved
  code so user UDFs can read self-configured values without extending
  the Python UDF schema

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added engine ddl-change Changes to the TexeraDB DDL frontend Changes related to the frontend GUI dev common agent-service labels May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-service common ddl-change Changes to the TexeraDB DDL dev engine frontend Changes related to the frontend GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant