tools.py 5.34 KB
Newer Older
1
2
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
Timothy J. Baek's avatar
Timothy J. Baek committed
3
4
import time
import logging
5
6
7
8
from sqlalchemy import String, Column, BigInteger
from sqlalchemy.orm import Session

from apps.webui.internal.db import Base, JSONField
Timothy J. Baek's avatar
Timothy J. Baek committed
9
from apps.webui.models.users import Users
Timothy J. Baek's avatar
Timothy J. Baek committed
10
11

import json
12
13
import copy

Timothy J. Baek's avatar
Timothy J. Baek committed
14
15
16
17
18
19
20
21
22
23
24

from config import SRC_LOG_LEVELS

log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"])

####################
# Tools DB Schema
####################


25
26
class Tool(Base):
    __tablename__ = "tool"
Timothy J. Baek's avatar
Timothy J. Baek committed
27

28
29
30
31
32
33
34
35
36
    id = Column(String, primary_key=True)
    user_id = Column(String)
    name = Column(String)
    content = Column(String)
    specs = Column(JSONField)
    meta = Column(JSONField)
    valves = Column(JSONField)
    updated_at = Column(BigInteger)
    created_at = Column(BigInteger)
Timothy J. Baek's avatar
Timothy J. Baek committed
37
38
39
40


class ToolMeta(BaseModel):
    description: Optional[str] = None
41
    manifest: Optional[dict] = {}
Timothy J. Baek's avatar
Timothy J. Baek committed
42
43
44
45
46
47
48


class ToolModel(BaseModel):
    id: str
    user_id: str
    name: str
    content: str
Timothy J. Baek's avatar
Timothy J. Baek committed
49
    specs: List[dict]
Timothy J. Baek's avatar
Timothy J. Baek committed
50
51
52
53
    meta: ToolMeta
    updated_at: int  # timestamp in epoch
    created_at: int  # timestamp in epoch

54
55
    model_config = ConfigDict(from_attributes=True)

Timothy J. Baek's avatar
Timothy J. Baek committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

####################
# Forms
####################


class ToolResponse(BaseModel):
    id: str
    user_id: str
    name: str
    meta: ToolMeta
    updated_at: int  # timestamp in epoch
    created_at: int  # timestamp in epoch


class ToolForm(BaseModel):
    id: str
    name: str
    content: str
    meta: ToolMeta


Timothy J. Baek's avatar
Timothy J. Baek committed
78
79
80
81
class ToolValves(BaseModel):
    valves: Optional[dict] = None


Timothy J. Baek's avatar
Timothy J. Baek committed
82
83
84
class ToolsTable:

    def insert_new_tool(
85
        self, db: Session, user_id: str, form_data: ToolForm, specs: List[dict]
Timothy J. Baek's avatar
Timothy J. Baek committed
86
87
88
89
90
91
92
93
94
95
96
97
    ) -> Optional[ToolModel]:
        tool = ToolModel(
            **{
                **form_data.model_dump(),
                "specs": specs,
                "user_id": user_id,
                "updated_at": int(time.time()),
                "created_at": int(time.time()),
            }
        )

        try:
98
99
100
101
            result = Tool(**tool.dict())
            db.add(result)
            db.commit()
            db.refresh(result)
Timothy J. Baek's avatar
Timothy J. Baek committed
102
            if result:
103
                return ToolModel.model_validate(result)
Timothy J. Baek's avatar
Timothy J. Baek committed
104
105
            else:
                return None
Timothy J. Baek's avatar
fix  
Timothy J. Baek committed
106
107
        except Exception as e:
            print(f"Error creating tool: {e}")
Timothy J. Baek's avatar
Timothy J. Baek committed
108
109
            return None

110
    def get_tool_by_id(self, db: Session, id: str) -> Optional[ToolModel]:
Timothy J. Baek's avatar
Timothy J. Baek committed
111
        try:
112
113
            tool = db.get(Tool, id)
            return ToolModel.model_validate(tool)
Timothy J. Baek's avatar
Timothy J. Baek committed
114
115
116
        except:
            return None

117
118
    def get_tools(self, db: Session) -> List[ToolModel]:
        return [ToolModel.model_validate(tool) for tool in db.query(Tool).all()]
Timothy J. Baek's avatar
Timothy J. Baek committed
119

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
120
    def get_tool_valves_by_id(self, id: str) -> Optional[dict]:
Timothy J. Baek's avatar
Timothy J. Baek committed
121
122
        try:
            tool = Tool.get(Tool.id == id)
Timothy J. Baek's avatar
Timothy J. Baek committed
123
            return tool.valves if tool.valves else {}
Timothy J. Baek's avatar
Timothy J. Baek committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
        except Exception as e:
            print(f"An error occurred: {e}")
            return None

    def update_tool_valves_by_id(self, id: str, valves: dict) -> Optional[ToolValves]:
        try:
            query = Tool.update(
                **{"valves": valves},
                updated_at=int(time.time()),
            ).where(Tool.id == id)
            query.execute()

            tool = Tool.get(Tool.id == id)
            return ToolValves(**model_to_dict(tool))
        except:
            return None

Timothy J. Baek's avatar
Timothy J. Baek committed
141
142
143
144
145
    def get_user_valves_by_id_and_user_id(
        self, id: str, user_id: str
    ) -> Optional[dict]:
        try:
            user = Users.get_user_by_id(user_id)
146
            user_settings = user.settings.model_dump()
Timothy J. Baek's avatar
Timothy J. Baek committed
147
148

            # Check if user has "tools" and "valves" settings
149
150
151
152
            if "tools" not in user_settings:
                user_settings["tools"] = {}
            if "valves" not in user_settings["tools"]:
                user_settings["tools"]["valves"] = {}
Timothy J. Baek's avatar
Timothy J. Baek committed
153

154
            return user_settings["tools"]["valves"].get(id, {})
Timothy J. Baek's avatar
Timothy J. Baek committed
155
156
157
158
159
160
161
162
163
        except Exception as e:
            print(f"An error occurred: {e}")
            return None

    def update_user_valves_by_id_and_user_id(
        self, id: str, user_id: str, valves: dict
    ) -> Optional[dict]:
        try:
            user = Users.get_user_by_id(user_id)
164
            user_settings = user.settings.model_dump()
Timothy J. Baek's avatar
Timothy J. Baek committed
165
166

            # Check if user has "tools" and "valves" settings
167
168
169
170
            if "tools" not in user_settings:
                user_settings["tools"] = {}
            if "valves" not in user_settings["tools"]:
                user_settings["tools"]["valves"] = {}
Timothy J. Baek's avatar
Timothy J. Baek committed
171

172
            user_settings["tools"]["valves"][id] = valves
Timothy J. Baek's avatar
Timothy J. Baek committed
173
174

            # Update the user settings in the database
175
            query = Users.update_user_by_id(user_id, {"settings": user_settings})
Timothy J. Baek's avatar
Timothy J. Baek committed
176
177
            query.execute()

178
            return user_settings["tools"]["valves"][id]
Timothy J. Baek's avatar
Timothy J. Baek committed
179
180
181
182
        except Exception as e:
            print(f"An error occurred: {e}")
            return None

Timothy J. Baek's avatar
Timothy J. Baek committed
183
184
    def update_tool_by_id(self, id: str, updated: dict) -> Optional[ToolModel]:
        try:
185
186
187
188
            db.query(Tool).filter_by(id=id).update(
                {**updated, "updated_at": int(time.time())}
            )
            return self.get_tool_by_id(db, id)
Timothy J. Baek's avatar
Timothy J. Baek committed
189
190
191
        except:
            return None

192
    def delete_tool_by_id(self, db: Session, id: str) -> bool:
Timothy J. Baek's avatar
Timothy J. Baek committed
193
        try:
194
            db.query(Tool).filter_by(id=id).delete()
Timothy J. Baek's avatar
Timothy J. Baek committed
195
196
197
198
199
            return True
        except:
            return False


200
Tools = ToolsTable()