feat(tool-config): add categories, interfaces, and config management

Add support for tool categories, interface types, and per-tool configuration.

Backend:
- Add category and interfaces fields to ToolType model
- Create ToolConfig model for storing tool-specific settings
- Add tool_configs API endpoints (CRUD)
- Update built-in tool types with categories and interfaces:
  - code-server: editor, [web]
  - jupyter-notebook: notebook, [web]
  - opencode: ai-assistant, [terminal]
- Update instance API to include tool type interfaces
- Create Alembic migrations 0008 and 0009

Frontend:
- Update ToolType and Session interfaces with new fields
- Conditionally show Open/Terminal buttons based on tool interfaces
- Add API client for tool configs

OpenSpec: tool-config-management change created and implemented.
This commit is contained in:
Fusion
2026-05-20 11:03:09 +02:00
parent 74b5d0dc8c
commit 63ae706dd0
17 changed files with 539 additions and 17 deletions
+39
View File
@@ -0,0 +1,39 @@
import uuid
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, String, Text
from sqlalchemy import Uuid as UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.models.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
if TYPE_CHECKING:
from src.models.project import Project
from src.models.tool_type import ToolType
from src.models.user import User
class ToolConfig(UUIDPrimaryKeyMixin, TimestampMixin, Base):
__tablename__ = "tool_configs"
user_id: Mapped[uuid.UUID] = mapped_column(
UUID(), ForeignKey("users.id"), nullable=False
)
tool_type_id: Mapped[uuid.UUID] = mapped_column(
UUID(), ForeignKey("tool_types.id"), nullable=False
)
project_id: Mapped[uuid.UUID | None] = mapped_column(
UUID(), ForeignKey("projects.id"), nullable=True
)
key: Mapped[str] = mapped_column(String(255), nullable=False)
value: Mapped[str] = mapped_column(Text, nullable=False)
config_type: Mapped[str] = mapped_column(
String(20), nullable=False, default="env"
) # "env" or "file"
file_path: Mapped[str | None] = mapped_column(
String(1024), nullable=True
) # Only for file type
user: Mapped["User"] = relationship()
tool_type: Mapped["ToolType"] = relationship()
project: Mapped["Project | None"] = relationship()