Skip to content

Commit b0938d9

Browse files
authored
Add org & role (#226)
* Add organizataion & role * update the frontend Signed-off-by: kerthcet <kerthcet@gmail.com> --------- Signed-off-by: kerthcet <kerthcet@gmail.com>
1 parent 99558ff commit b0938d9

54 files changed

Lines changed: 2582 additions & 965 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# Runtime configurations
22
ALPHATRION_LOG_LEVEL=INFO
3-
ALPHATRION_AUTO_CLEANUP=true
43

54
# Database configurations
65
ALPHATRION_METADATA_DB_URL=postgresql+psycopg2://alphatrion:alphatr1on@localhost:5432/alphatrion

.env.integration-test

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ ALPHATRION_METADATA_DB_URL=postgresql+psycopg2://alphatrion:alphatr1on@localhost
22
ALPHATRION_ARTIFACT_REGISTRY_URL=localhost:5001
33
ALPHATRION_ARTIFACT_INSECURE=true
44
ALPHATRION_LOG_LEVEL=INFO
5-
ALPHATRION_AUTO_CLEANUP=true
65
ALPHATRION_ENABLE_TRACING=true
76

87
ALPHATRION_CLICKHOUSE_ENABLE_BATCH=true

.env.test

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ ALPHATRION_METADATA_INIT_TABLES=true
22
ALPHATRION_METADATA_DB_URL=sqlite:///:memory:
33
ALPHATRION_ARTIFACT_REGISTRY_URL=localhost:5001
44
ALPHATRION_ARTIFACT_INSECURE=true
5-
ALPHATRION_LOG_LEVEL=INFO
6-
ALPHATRION_AUTO_CLEANUP=true
5+
ALPHATRION_LOG_LEVEL=INFO

alphatrion/agents/claude.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ def handle_stop():
245245
if not user_id and session:
246246
user_id = str(session.user_id)
247247

248+
user = metadb.get_user(user_id=uuid.UUID(user_id))
249+
248250
if not team_id and session:
249251
team_id = str(session.team_id)
250252

@@ -286,6 +288,7 @@ def handle_stop():
286288
agent_id = metadb.create_agent(
287289
name="claude",
288290
type=AgentType.CLAUDE,
291+
org_id=user.org_id,
289292
team_id=uuid.UUID(team_id),
290293
user_id=uuid.UUID(user_id),
291294
)
@@ -299,6 +302,7 @@ def handle_stop():
299302
db_session = metadb._session()
300303
session = AgentSession(
301304
uuid=session_uuid,
305+
org_id=user.org_id,
302306
agent_id=agent_id,
303307
team_id=uuid.UUID(team_id),
304308
user_id=uuid.UUID(user_id),
@@ -589,6 +593,7 @@ def process_transcript_incremental(
589593
# Create run with aggregated tokens
590594
run_id = metadb.create_run(
591595
session_id=uuid.UUID(session_id),
596+
org_id=session.org_id,
592597
team_id=session.team_id,
593598
user_id=session.user_id,
594599
status=run_status,

alphatrion/experiment/base.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,8 @@ def _start(
224224

225225
# reset to running status, also need to reset the tokens.
226226
if usage and "total_tokens" in usage:
227-
# delete the tokens in the usage
228-
usage.delete("total_tokens")
229-
usage.delete("input_tokens")
230-
usage.delete("output_tokens")
227+
# delete the tokens in the usage - set to None instead of empty dict
228+
usage = None
231229
self._runtime._metadb.update_experiment(
232230
experiment_id=self._id,
233231
status=Status.RUNNING,
@@ -241,6 +239,7 @@ def _start(
241239
else:
242240
self._id = self._runtime._metadb.create_experiment(
243241
name=name,
242+
org_id=self._runtime._org_id,
244243
team_id=self._runtime._team_id,
245244
user_id=self._runtime._user_id,
246245
description=description,
@@ -262,6 +261,10 @@ def _start(
262261
def id(self) -> uuid.UUID:
263262
return self._id
264263

264+
@property
265+
def team_id(self) -> uuid.UUID:
266+
return self._runtime.team_id
267+
265268
@property
266269
def config(self) -> ExperimentConfig:
267270
return self._config

alphatrion/log/log.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ async def log_metrics(metrics: dict[str, float]) -> bool:
114114
runtime._metadb.create_metric(
115115
key=key,
116116
value=value,
117-
team_id=runtime._team_id,
117+
org_id=runtime.org_id,
118+
team_id=runtime.team_id,
118119
experiment_id=exp_id,
119120
run_id=run_id,
120121
)
@@ -183,6 +184,7 @@ async def log_dataset(
183184

184185
id = runtime.metadb.create_dataset(
185186
name=name,
187+
org_id=runtime.org_id,
186188
team_id=runtime.team_id,
187189
user_id=runtime.user_id,
188190
path=path,
@@ -198,6 +200,7 @@ async def log_dataset(
198200
)
199201
id = runtime.metadb.create_dataset(
200202
name=name,
203+
org_id=runtime.org_id,
201204
team_id=runtime.team_id,
202205
user_id=runtime.user_id,
203206
path=path,

alphatrion/run/run.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def _get_obj(self):
2929

3030
def start(self, call_func: CallableEntry) -> None:
3131
self._id = self._runtime.metadb.create_run(
32+
org_id=self._runtime.org_id,
3233
team_id=self._runtime.team_id,
3334
user_id=self._runtime.user_id,
3435
experiment_id=self._exp_id,

alphatrion/runtime/runtime.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
def init(
1313
user_id: uuid.UUID,
1414
team_id: uuid.UUID | None = None,
15+
org_id: uuid.UUID | None = None,
1516
):
1617
"""
1718
Initialize the AlphaTrion runtime environment.
@@ -20,13 +21,13 @@ def init(
2021
user_id: The user ID for the current user. You can generate a UUID
2122
using `uuid.uuid4()`.
2223
team_id: The team ID for the current user. If not provided, will look
23-
for the first team
24-
associated with the user in the database.
24+
for the first team associated with the user in the database.
2525
"""
2626
global __RUNTIME__
2727
__RUNTIME__ = Runtime(
2828
user_id=user_id,
2929
team_id=team_id,
30+
org_id=org_id,
3031
)
3132

3233

@@ -42,6 +43,7 @@ class Runtime:
4243
__slots__ = (
4344
"_user_id",
4445
"_team_id",
46+
"_org_id",
4547
"_metadb",
4648
"_tracestore",
4749
"_artifact",
@@ -53,6 +55,7 @@ def __init__(
5355
self,
5456
user_id: uuid.UUID,
5557
team_id: uuid.UUID | None = None,
58+
org_id: uuid.UUID | None = None,
5659
):
5760
storage_runtime.init()
5861
self._metadb = storage_runtime.storage_runtime().metadb
@@ -61,6 +64,7 @@ def __init__(
6164

6265
self._user_id = user_id
6366
self._team_id = team_id
67+
self._org_id = org_id
6468

6569
if team_id is None:
6670
# If team_id is not provided, look for the first team associated with
@@ -73,6 +77,13 @@ def __init__(
7377
)
7478
self._team_id = teams[0].uuid
7579

80+
if org_id is None:
81+
# Look up org_id from user or team
82+
user = self._metadb.get_user(user_id)
83+
if not user:
84+
raise ValueError(f"User {user_id} not found in the database.")
85+
self._org_id = user.org_id
86+
7687
self._root_path = os.getenv(envs.ROOT_PATH, os.path.expanduser("~/.alphatrion"))
7788
if not os.path.exists(self._root_path):
7889
os.makedirs(self._root_path, exist_ok=True)
@@ -97,6 +108,10 @@ def user_id(self) -> uuid.UUID:
97108
def team_id(self) -> uuid.UUID:
98109
return self._team_id
99110

111+
@property
112+
def org_id(self) -> uuid.UUID:
113+
return self._org_id
114+
100115
@property
101116
def root_path(self) -> str:
102117
return self._root_path

alphatrion/server/cmd/app.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from fastapi.middleware.cors import CORSMiddleware
99
from strawberry.fastapi import GraphQLRouter
1010

11+
from alphatrion.server.graphql.context import get_context
1112
from alphatrion.server.graphql.schema import schema
1213

1314
# Configure logging
@@ -99,8 +100,8 @@ async def receive():
99100
return response
100101

101102

102-
# Create GraphQL router
103-
graphql_app = GraphQLRouter(schema)
103+
# Create GraphQL router with context
104+
graphql_app = GraphQLRouter(schema, context_getter=get_context)
104105

105106
# Mount /graphql endpoint
106107
app.include_router(graphql_app, prefix="/graphql")

alphatrion/server/cmd/main.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ def main():
9898
default="Default Team",
9999
help="Team name (default: Default Team)",
100100
)
101+
init.add_argument(
102+
"--org-name",
103+
type=str,
104+
default=None,
105+
help="Organization name (auto-generated if not provided)",
106+
)
101107
init.set_defaults(func=init_command)
102108

103109
# run command (with subcommands)
@@ -173,32 +179,38 @@ def init_command(args):
173179
else f"{user_name.lower().replace(' ', '.')}@inftyai.com"
174180
)
175181
team_name = args.team_name
182+
org_name = args.org_name if args.org_name else fake.company()
176183

177184
try:
178185
metadb = runtime.storage_runtime().metadb
179186

180187
console.print()
188+
# Create organization
189+
console.print(Text(f"🏢 Creating organization: {org_name}", style="bold cyan"))
190+
org_id = metadb.create_organization(name=org_name)
181191
# Create user
182192
console.print(
183193
Text(f"👤 Creating user: {user_name} ({email})", style="bold cyan")
184194
)
185-
user_id = metadb.create_user(username=user_name, email=email)
195+
user_id = metadb.create_user(name=user_name, email=email, org_id=org_id)
186196

187197
# Create team
188198
console.print(Text(f"🏢 Creating team: {team_name}", style="bold cyan"))
189199
team_id = metadb.create_team(
190-
name=team_name, description=f"Team for {user_name}"
200+
name=team_name, description=f"Team for {user_name}", org_id=org_id
191201
)
192202
# Add user to team
193203
metadb.add_user_to_team(user_id=user_id, team_id=team_id)
194204

195205
console.print()
196206
console.print(Text("✅ Initialization successful!", style="bold green"))
197207
console.print()
198-
console.print(Text("📋 Your user ID:", style="bold yellow"))
199-
console.print(Text(f" {user_id}", style="bold cyan"))
208+
console.print(Text("📋 Your organization ID:", style="bold yellow"))
209+
console.print(Text(f" {org_id}", style="bold cyan"))
200210
console.print(Text(" Your team ID:", style="bold yellow"))
201211
console.print(Text(f" {team_id}", style="bold cyan"))
212+
console.print(Text(" Your user ID:", style="bold yellow"))
213+
console.print(Text(f" {user_id}", style="bold cyan"))
202214
console.print()
203215
console.print(
204216
Text(
@@ -296,6 +308,7 @@ def run_agent_command(args):
296308
agent_id = metadb.create_agent(
297309
name=agent_name,
298310
type=agent_type,
311+
org_id=metadb.get_user(uuid.UUID(user_id)).org_id,
299312
team_id=uuid.UUID(team_id),
300313
user_id=uuid.UUID(user_id),
301314
)
@@ -529,12 +542,34 @@ def start_dashboard(args):
529542
# Create HTTP client for proxying requests to backend
530543
http_client = httpx.AsyncClient(base_url=args.backend_url, timeout=30.0)
531544

532-
# Endpoint to get current user ID (for frontend)
545+
# Endpoint to get current user ID and org ID (for frontend)
533546
@app.get("/api/config")
534547
async def get_config():
548+
import contextlib
549+
import uuid
550+
551+
from alphatrion.storage import runtime as storage_runtime
552+
553+
# Initialize storage if not already done
554+
with contextlib.suppress(Exception):
555+
storage_runtime.init()
556+
535557
config = {"userId": app.state.user_id}
558+
559+
# Look up user's org_id
560+
try:
561+
metadb = storage_runtime.storage_runtime().metadb
562+
user = metadb.get_user(user_id=uuid.UUID(app.state.user_id))
563+
if user:
564+
config["orgId"] = str(user.org_id)
565+
except Exception as e:
566+
console.print(
567+
Text(f"Warning: Could not fetch user org_id: {e}", style="yellow")
568+
)
569+
536570
if hasattr(app.state, "team_id"):
537571
config["teamId"] = app.state.team_id
572+
538573
return config
539574

540575
# Proxy /graphql requests to backend (MUST be before catch-all route)

0 commit comments

Comments
 (0)