Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 13 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,17 @@ logs/*
.env
*.egg-info/*
site/
build/
dist/
**/metadata/*.json

# Studio frontend build artifacts
**/node_modules/*
**/.svelte-kit/*
studio/frontend/build/

# Studio runtime data
studio/.executions_history.json
studio/.executions/*

# Studio config
studio/config/custom_models.yaml
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,57 @@ setup-dev: ## Install development dependencies
@echo "Installing SyGra Core, Extra and Development dependencies"
$(UV) sync --extra dev --extra ui

########################################################################################################################
# SYGRA STUDIO
########################################################################################################################

# Studio directories
STUDIO_DIR = studio
STUDIO_FRONTEND_DIR = $(STUDIO_DIR)/frontend
STUDIO_BUILD_DIR = $(STUDIO_FRONTEND_DIR)/build

# Studio configuration (can be overridden: make studio TASKS_DIR=./my/tasks PORT=9000)
TASKS_DIR ?= ./tasks/examples
PORT ?= 8000

.PHONY: studio
studio: studio-build ## Launch SyGra Studio (builds frontend if needed, starts server)
@echo "🚀 Starting SyGra Studio..."
@echo " Tasks: $(TASKS_DIR)"
@echo " Port: $(PORT)"
$(UV) run $(PYTHON) -m studio.server --svelte --tasks-dir $(TASKS_DIR) --port $(PORT)

.PHONY: studio-build
studio-build: ## Build the Studio frontend (only if not already built)
@if [ ! -d "$(STUDIO_BUILD_DIR)" ] || [ ! -f "$(STUDIO_BUILD_DIR)/index.html" ]; then \
echo "📦 Building Studio frontend..."; \
cd $(STUDIO_FRONTEND_DIR) && npm install && npm run build; \
else \
echo "✅ Studio frontend already built. Use 'make studio-rebuild' to force rebuild."; \
fi

.PHONY: studio-rebuild
studio-rebuild: ## Force rebuild the Studio frontend
@echo "🔨 Rebuilding Studio frontend..."
cd $(STUDIO_FRONTEND_DIR) && npm install && npm run build

.PHONY: studio-dev
studio-dev: ## Launch Studio in development mode (hot-reload for frontend)
@echo "🔧 Starting Studio in development mode..."
@echo " Backend: http://localhost:$(PORT)"
@echo " Frontend: http://localhost:5173 (with hot-reload)"
@echo ""
@echo "Run these commands in separate terminals:"
@echo " Terminal 1: $(UV) run $(PYTHON) -m studio.server --tasks-dir $(TASKS_DIR) --port $(PORT)"
@echo " Terminal 2: cd $(STUDIO_FRONTEND_DIR) && npm run dev"

.PHONY: studio-clean
studio-clean: ## Clean Studio frontend build artifacts
@echo "🧹 Cleaning Studio frontend build..."
rm -rf $(STUDIO_BUILD_DIR)
rm -rf $(STUDIO_FRONTEND_DIR)/node_modules
rm -rf $(STUDIO_FRONTEND_DIR)/.svelte-kit

########################################################################################################################
# TESTING
########################################################################################################################
Expand Down
1 change: 0 additions & 1 deletion docs/eval/metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,3 @@ When adding new metrics documentation:
3. Explain the "why" behind design decisions
4. Cover edge cases and common pitfalls
5. Provide real-world use case scenarios

11 changes: 10 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ dependencies = [
"boto3>=1.40.71,<2.0.0",
"google-auth>=2.43.0,<3.0.0",
"google-cloud-aiplatform>=1.128.0,<2.0.0",
"fastapi (>=0.124.4,<0.125.0)",
"uvicorn (>=0.38.0,<0.39.0)",
"debugpy (>=1.8.19,<2.0.0)",
]

[project.optional-dependencies]
Expand Down Expand Up @@ -96,13 +99,16 @@ Issues = "https://github.com/ServiceNow/SyGra/issues"
Discussions = "https://github.com/ServiceNow/SyGra/discussions"

[tool.hatch.build.targets.wheel]
packages = ["sygra"]
packages = ["sygra", "studio"]
include = [
"sygra/**/*.yaml",
"sygra/**/*.yml",
"sygra/**/*.jinja2",
"sygra/**/*.j2",
"sygra/**/*.json",
"studio/**/*.yaml",
"studio/**/*.yml",
"studio/**/*.json",
]

# --- Tool configurations ---
Expand Down Expand Up @@ -157,3 +163,6 @@ exclude = [
module = ["tests.*"]
disallow_untyped_defs = false
check_untyped_defs = false

[tool.poetry.group.dev.dependencies]
uvicorn = "^0.38.0"
126 changes: 126 additions & 0 deletions studio/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""
SyGra Studio Integration

This module provides seamless integration between SyGra workflows and Studio
UI visualization. It enables:
- Converting SyGra YAML configs to visualization-friendly graph format
- Running SyGra workflows from a web UI
- Real-time workflow execution monitoring

Usage:
# Start the UI server
from studio import run_server
run_server(tasks_dir="./tasks/examples", port=8000)

# Or use the CLI
python -m studio.server --tasks-dir ./tasks/examples

# Build graph from YAML
from studio import build_graph_from_yaml
graph = build_graph_from_yaml("./tasks/examples/glaive_code_assistant/graph_config.yaml")

# Convert to OpenFlow format
from studio import convert_sygra_to_openflow
openflow = convert_sygra_to_openflow("./tasks/examples/glaive_code_assistant/graph_config.yaml")
"""

from studio.converter import (
SygraToStudioConverter,
convert_sygra_to_openflow,
)
from studio.graph_builder import (
SygraGraphBuilder,
build_graph_from_yaml,
build_graph_from_config,
)
from studio.models import (
WorkflowNode,
WorkflowEdge,
WorkflowGraph,
WorkflowExecution,
ExecutionStatus,
NodeType,
NodePosition,
NodeSize,
ModelConfig,
PromptMessage,
EdgeCondition,
NodeExecutionState,
WorkflowListItem,
ExecutionRequest,
ExecutionResponse,
)
from studio.execution_manager import (
ExecutionManager,
ExecutionCallback,
SygraExecutionRunner,
get_execution_manager,
)

# Server components are lazily imported to avoid circular import warnings
# when running `python -m studio.server`

def create_server(*args, **kwargs):
"""Create and return the Studio server instance (lazy import)."""
from studio.server import create_server as _create_server
return _create_server(*args, **kwargs)


def run_server(*args, **kwargs):
"""Run the Studio server (lazy import)."""
from studio.server import run_server as _run_server
return _run_server(*args, **kwargs)

def create_app(*args, **kwargs):
"""Create the FastAPI application (lazy import)."""
from studio.api import create_app as _create_app
return _create_app(*args, **kwargs)


def __getattr__(name):
"""Lazy import for server components."""
if name == "create_server":
from studio.server import create_server
return create_server
elif name == "run_server":
from studio.server import run_server
return run_server
elif name == "create_app":
from studio.api import create_app
return create_app
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

__all__ = [
# Converter
"SygraToStudioConverter",
"convert_sygra_to_openflow",
# Graph Builder
"SygraGraphBuilder",
"build_graph_from_yaml",
"build_graph_from_config",
# Models
"WorkflowNode",
"WorkflowEdge",
"WorkflowGraph",
"WorkflowExecution",
"ExecutionStatus",
"NodeType",
"NodePosition",
"NodeSize",
"ModelConfig",
"PromptMessage",
"EdgeCondition",
"NodeExecutionState",
"WorkflowListItem",
"ExecutionRequest",
"ExecutionResponse",
# Execution
"ExecutionManager",
"ExecutionCallback",
"SygraExecutionRunner",
"get_execution_manager",
# Server
"create_server",
"run_server",
"create_app",
]
Loading