Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
05031ea
README.md fix
MrBlack1995 Nov 7, 2025
f7dbc21
Merge pull request #37 from MrBlack1995/main
nehmetohmedb Nov 7, 2025
f274b06
README optical fix
MrBlack1995 Nov 8, 2025
f73f931
Logo alignment with headline
MrBlack1995 Nov 8, 2025
2ddf557
Centering logo and text
MrBlack1995 Nov 8, 2025
4217819
Merge branch 'databrickslabs:main' into main
MrBlack1995 Nov 8, 2025
45b7f57
Merge pull request #38 from MrBlack1995/main
nehmetohmedb Nov 8, 2025
6a5ca0b
Add measure conversion infrastructure
david-schwarz-db Nov 17, 2025
1360236
Migrate yaml2dax and reorganize converters package structure
david-schwarz-db Nov 17, 2025
3a7d2b3
Backend changes KPI parsers
david-schwarz-db Nov 18, 2025
44e63b4
outbound metrics-conversion refactoring
david-schwarz-db Nov 28, 2025
7605a91
Inbound connector integration
david-schwarz-db Dec 1, 2025
d70972e
Frontend documentation around MetricsConverter
david-schwarz-db Dec 4, 2025
2c9867b
Measure Conversion Pipeline tooling UI experience
david-schwarz-db Dec 4, 2025
d368393
Frontend Documentation
david-schwarz-db Dec 4, 2025
43a9c94
error handling typescirpt
david-schwarz-db Dec 4, 2025
0a265f6
1. Exported the MeasureConverterConfig interface from the component
david-schwarz-db Dec 4, 2025
c3cfd35
Config passing fix from frontend to backend
david-schwarz-db Dec 5, 2025
a04fc2e
super().__init__() - didn't pass kwargs, breaking the tool
david-schwarz-db Dec 5, 2025
fb02f5d
Taskform compiler
david-schwarz-db Dec 5, 2025
be0277e
Generator passing variables change
david-schwarz-db Dec 5, 2025
23c684f
Error: Unsupported inbound_connector 'None' fix
david-schwarz-db Dec 5, 2025
7142a96
Token passing
david-schwarz-db Dec 5, 2025
c00f791
Adding azure identity service
david-schwarz-db Dec 5, 2025
94fe30e
Mesure Converter channeling
david-schwarz-db Dec 9, 2025
fdb6816
Tool factory debugger
david-schwarz-db Dec 9, 2025
eb2a8f5
Task helper config
david-schwarz-db Dec 9, 2025
19edbce
Crew parameter passing
david-schwarz-db Dec 9, 2025
8737a24
PL tracking
david-schwarz-db Dec 9, 2025
c03f90e
Logging change
david-schwarz-db Dec 9, 2025
2338f74
Fixing base measure filter passing
david-schwarz-db Dec 9, 2025
d4c3e79
SQL separator for output formatting
david-schwarz-db Dec 9, 2025
8352fba
Disabling result crunching for PBI DAX
david-schwarz-db Dec 10, 2025
76ac030
Output / Input formatting
david-schwarz-db Dec 10, 2025
c3a544c
Avoid App.db deployment
david-schwarz-db Dec 10, 2025
ac2b343
app.db deployment
david-schwarz-db Dec 11, 2025
aabfb18
Remove YAML as target dialect
david-schwarz-db Dec 11, 2025
f18eb79
SQL fix
david-schwarz-db Dec 11, 2025
ec40c08
YAML removal
david-schwarz-db Dec 11, 2025
85412b3
SQL logging
david-schwarz-db Dec 11, 2025
a6da6fb
Adding temp db to path
david-schwarz-db Dec 11, 2025
01d15d6
SQL generation schema
david-schwarz-db Dec 11, 2025
125af5e
YAML to SQL change
david-schwarz-db Dec 11, 2025
52f0bc6
Debugging notes
david-schwarz-db Dec 11, 2025
11d337b
SQL Model change for display
david-schwarz-db Dec 12, 2025
37bcaa2
Import change
david-schwarz-db Dec 12, 2025
a384351
PowerBI to UC Metrics error fix (intermdiary formt)
david-schwarz-db Dec 12, 2025
155be00
PowerBI --> SQL conversion fix
david-schwarz-db Dec 12, 2025
7c53c43
Removal of YAML dropdown option
david-schwarz-db Dec 12, 2025
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
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Kasal
![Kasal Logo](./src/docs/images/logo.png)
<h1 style="display: flex; align-items: center; gap: 10px;"><img src="./src/frontend/public/kasal-icon-32.png" alt="Kasal Logo" style="height: 1.2em;"/> Kasal</h1>
**Build intelligent AI agent workflows with visual simplicity and enterprise power.**

[![YouTube Video](https://img.youtube.com/vi/0d5e5rSe5JI/0.jpg)](https://www.youtube.com/watch?v=0d5e5rSe5JI)
Expand Down Expand Up @@ -35,7 +34,7 @@ Quick setup for testing and development - requires Python 3.9+ and Node.js.

## See It in Action

![Kasal UI Screenshot](src/images/kasal-ui-screenshot.png)
![Kasal UI Screenshot](./src/frontend/public/kasal-ui-screenshot.png)
*Visual workflow designer for creating AI agent collaborations*

Create your first agent workflow in under 2 minutes:
Expand Down
127 changes: 127 additions & 0 deletions src/backend/migrations/versions/cf0a3479e307_add_converter_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
"""add_converter_models

Revision ID: cf0a3479e307
Revises: 665ffadb181e
Create Date: 2025-12-01 07:31:43.174060

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = 'cf0a3479e307'
down_revision: Union[str, None] = '665ffadb181e'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# Create conversion_history table
op.create_table(
'conversion_history',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('execution_id', sa.String(length=100), nullable=True),
sa.Column('job_id', sa.String(length=100), nullable=True),
sa.Column('source_format', sa.String(length=50), nullable=False),
sa.Column('target_format', sa.String(length=50), nullable=False),
sa.Column('input_data', sa.JSON(), nullable=True),
sa.Column('input_summary', sa.Text(), nullable=True),
sa.Column('output_data', sa.JSON(), nullable=True),
sa.Column('output_summary', sa.Text(), nullable=True),
sa.Column('configuration', sa.JSON(), nullable=True),
sa.Column('status', sa.String(length=20), nullable=False, server_default='pending'),
sa.Column('error_message', sa.Text(), nullable=True),
sa.Column('warnings', sa.JSON(), nullable=True),
sa.Column('measure_count', sa.Integer(), nullable=True),
sa.Column('execution_time_ms', sa.Integer(), nullable=True),
sa.Column('converter_version', sa.String(length=50), nullable=True),
sa.Column('extra_metadata', sa.JSON(), nullable=True),
sa.Column('group_id', sa.String(length=100), nullable=True),
sa.Column('created_by_email', sa.String(length=255), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.PrimaryKeyConstraint('id')
)

# Create indexes for conversion_history
op.create_index('ix_conversion_history_execution_id', 'conversion_history', ['execution_id'])
op.create_index('ix_conversion_history_job_id', 'conversion_history', ['job_id'])
op.create_index('ix_conversion_history_source_format', 'conversion_history', ['source_format'])
op.create_index('ix_conversion_history_target_format', 'conversion_history', ['target_format'])
op.create_index('ix_conversion_history_group_id', 'conversion_history', ['group_id'])
op.create_index('ix_conversion_history_group_created', 'conversion_history', ['group_id', 'created_at'])
op.create_index('ix_conversion_history_status_created', 'conversion_history', ['status', 'created_at'])
op.create_index('ix_conversion_history_formats', 'conversion_history', ['source_format', 'target_format'])

# Create conversion_jobs table
op.create_table(
'conversion_jobs',
sa.Column('id', sa.String(length=100), nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('tool_id', sa.Integer(), nullable=True),
sa.Column('source_format', sa.String(length=50), nullable=False),
sa.Column('target_format', sa.String(length=50), nullable=False),
sa.Column('configuration', sa.JSON(), nullable=False),
sa.Column('status', sa.String(length=20), nullable=False, server_default='pending'),
sa.Column('progress', sa.Float(), nullable=True),
sa.Column('result', sa.JSON(), nullable=True),
sa.Column('error_message', sa.Text(), nullable=True),
sa.Column('execution_id', sa.String(length=100), nullable=True),
sa.Column('history_id', sa.Integer(), nullable=True),
sa.Column('extra_metadata', sa.JSON(), nullable=True),
sa.Column('group_id', sa.String(length=100), nullable=True),
sa.Column('created_by_email', sa.String(length=255), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('started_at', sa.DateTime(), nullable=True),
sa.Column('completed_at', sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(['tool_id'], ['tools.id']),
sa.ForeignKeyConstraint(['history_id'], ['conversion_history.id']),
sa.PrimaryKeyConstraint('id')
)

# Create indexes for conversion_jobs
op.create_index('ix_conversion_jobs_execution_id', 'conversion_jobs', ['execution_id'])
op.create_index('ix_conversion_jobs_group_id', 'conversion_jobs', ['group_id'])
op.create_index('ix_conversion_jobs_group_created', 'conversion_jobs', ['group_id', 'created_at'])
op.create_index('ix_conversion_jobs_status', 'conversion_jobs', ['status'])

# Create saved_converter_configurations table
op.create_table(
'saved_converter_configurations',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('source_format', sa.String(length=50), nullable=False),
sa.Column('target_format', sa.String(length=50), nullable=False),
sa.Column('configuration', sa.JSON(), nullable=False),
sa.Column('use_count', sa.Integer(), nullable=False, server_default='0'),
sa.Column('last_used_at', sa.DateTime(), nullable=True),
sa.Column('is_public', sa.Boolean(), nullable=False, server_default='0'),
sa.Column('is_template', sa.Boolean(), nullable=False, server_default='0'),
sa.Column('tags', sa.JSON(), nullable=True),
sa.Column('extra_metadata', sa.JSON(), nullable=True),
sa.Column('group_id', sa.String(length=100), nullable=True),
sa.Column('created_by_email', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')),
sa.PrimaryKeyConstraint('id')
)

# Create indexes for saved_converter_configurations
op.create_index('ix_saved_converter_configurations_group_id', 'saved_converter_configurations', ['group_id'])
op.create_index('ix_saved_converter_configurations_created_by_email', 'saved_converter_configurations', ['created_by_email'])
op.create_index('ix_saved_configs_group_user', 'saved_converter_configurations', ['group_id', 'created_by_email'])
op.create_index('ix_saved_configs_formats', 'saved_converter_configurations', ['source_format', 'target_format'])
op.create_index('ix_saved_configs_public', 'saved_converter_configurations', ['is_public', 'is_template'])


def downgrade() -> None:
# Drop tables in reverse order (respecting foreign key constraints)
op.drop_table('saved_converter_configurations')
op.drop_table('conversion_jobs')
op.drop_table('conversion_history')
5 changes: 5 additions & 0 deletions src/backend/src/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
from src.api.documentation_embeddings_router import router as documentation_embeddings_router
from src.api.database_management_router import router as database_management_router
from src.api.genie_router import router as genie_router
from src.api.kpi_conversion_router import router as kpi_conversion_router
from src.api.converter_router import router as converter_router

# Create the main API router
api_router = APIRouter()
Expand Down Expand Up @@ -95,6 +97,8 @@
api_router.include_router(documentation_embeddings_router)
api_router.include_router(database_management_router)
api_router.include_router(genie_router)
api_router.include_router(kpi_conversion_router)
api_router.include_router(converter_router)

__all__ = [
"api_router",
Expand Down Expand Up @@ -138,4 +142,5 @@
"database_management_router",
"genie_router",
"mlflow_router",
"kpi_conversion_router",
]
Loading