diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..52ffe1fb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,60 @@ +# Git +.git +.gitignore +.gitattributes + +# Documentation +*.md +docs/ +assets/ + +# IDE +.vscode/ +.cursor/ +.idea/ + +# Dependencies +node_modules/ +**/node_modules/ + +# Build outputs +dist/ +**/dist/ +build/ +**/build/ +out/ + +# Logs +*.log +logs/ + +# Environment +.env +.env.local +.env.*.local + +# OS +.DS_Store +Thumbs.db + +# Temporary files +tmp/ +temp/ +*.tmp +*.swp +*.swo + +# Test +coverage/ +.nyc_output/ + +# Mise +.mise.toml.local + +# Data +data/ +*.db +*.sqlite + +# Docker +docker-compose.override.yml diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 00000000..5be9cc79 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,394 @@ +# Memoh Docker Deployment Guide + +Deploy Memoh AI Agent System with Docker Compose in one command. + +## Quick Start + +### 1. Clone the Repository +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +``` + +### 2. One-Click Deployment +```bash +./deploy.sh +``` + +The script will automatically: +- Check Docker and Docker Compose installation +- Create `config.toml` configuration file (if not exists) +- Build MCP image +- Start all services + +### 3. Access the Application +- Web UI: http://localhost +- API Service: http://localhost:8080 +- Agent Gateway: http://localhost:8081 + +Default admin credentials: +- Username: `admin` +- Password: `admin123` (change in `config.toml`) + +## Manual Deployment + +If you prefer not to use the automated script: + +```bash +# 1. Create configuration file +cp docker/config/config.docker.toml config.toml + +# 2. Edit configuration (Important!) +nano config.toml + +# 3. Build MCP image +docker build -f docker/Dockerfile.mcp -t memoh-mcp:latest . + +# 4. Start services +docker compose up -d + +# 5. View logs +docker compose logs -f +``` + +## Architecture + +This deployment uses the host's Docker daemon to manage Bot containers: + +``` +Host Docker +├── memoh-postgres (PostgreSQL) +├── memoh-qdrant (Qdrant) +├── memoh-server (Main Service) ← Manages Bot containers via /var/run/docker.sock +├── memoh-agent (Agent Gateway) +├── memoh-web (Web Frontend) +└── memoh-bot-* (Bot containers, dynamically created by main service) +``` + +Advantages: +- ✅ Lightweight, no additional Docker daemon needed +- ✅ Better performance, uses host container runtime directly +- ✅ Easier to manage and debug +- ✅ Lower resource consumption + +## Common Commands + +### Using Docker Compose +```bash +docker compose up -d # Start services +docker compose down # Stop services +docker compose logs -f # View logs +docker compose ps # View status +docker compose restart # Restart services +``` + +### Bot Container Management + +View all Bot containers: +```bash +docker ps -a | grep memoh-bot +``` + +## Configuration + +### Environment Variables + +Configuration is managed through `config.toml` file. Key configuration items: + +```toml +# Admin account +[admin] +username = "admin" +password = "admin123" # Must change +email = "admin@yourdomain.com" + +# Auth configuration +[auth] +jwt_secret = "YZq8kXrW5dFpNt9mLxQvHbRjKsMnOePw" # Must change +jwt_expires_in = "168h" + +# PostgreSQL password +[postgres] +host = "postgres" +port = 5432 +user = "memoh" +password = "memoh123" # Must change +database = "memoh" +sslmode = "disable" +``` + +### Application Configuration (config.toml) + +Main configuration items: + +```toml +[postgres] +host = "postgres" +password = "your_secure_password" # Must change in config.toml + +[containerd] +socket_path = "unix:///var/run/docker.sock" # Use host Docker + +[qdrant] +base_url = "http://qdrant:6334" +``` + +## Service Overview + +| Service | Container Name | Ports | Description | +|---------|---------------|-------|-------------| +| postgres | memoh-postgres | - | PostgreSQL database (internal only) | +| qdrant | memoh-qdrant | - | Qdrant vector database (internal only) | +| docker-cli | memoh-docker-cli | - | Docker CLI (uses host Docker) | +| server | memoh-server | 8080 | Main service (Go) | +| agent | memoh-agent | 8081 | Agent Gateway (Bun) | +| web | memoh-web | 80 | Web frontend (Nginx) | + +## Data Persistence + +Data is stored in Docker volumes: + +```bash +# View volumes +docker volume ls | grep memoh + +# Backup database +docker compose exec postgres pg_dump -U memoh memoh > backup.sql +``` + +### Bot Container Management + +Bot containers are dynamically created by the main service and run directly on the host: + +```bash +# View all Bot containers +docker ps -a | grep memoh-bot + +# View Bot logs +docker logs + +# Enter Bot container +docker exec -it sh + +# Stop Bot container +docker stop +``` + +## Backup and Restore + +### Backup +```bash +# Create backup directory +mkdir -p backups + +# Backup database +docker compose exec postgres pg_dump -U memoh memoh > backups/postgres_$(date +%Y%m%d).sql + +# Backup Bot data +docker run --rm -v memoh_memoh_bot_data:/data -v $(pwd)/backups:/backup alpine \ + tar czf /backup/bot_data_$(date +%Y%m%d).tar.gz -C /data . + +# Backup configuration files +tar czf backups/config_$(date +%Y%m%d).tar.gz config.toml +``` + +### Restore +```bash +# Restore database +docker compose exec -T postgres psql -U memoh memoh < backups/postgres_20240101.sql + +# Restore Bot data +docker run --rm -v memoh_memoh_bot_data:/data -v $(pwd)/backups:/backup alpine \ + tar xzf /backup/bot_data_20240101.tar.gz -C /data +``` + +## Troubleshooting + +### Services Won't Start +```bash +# View detailed logs +docker compose logs server + +# Check configuration +docker compose config + +# Rebuild +docker compose build --no-cache +docker compose up -d +``` + +### Database Connection Failed +```bash +# Check if database is ready +docker compose exec postgres pg_isready -U memoh + +# Test connection +docker compose exec postgres psql -U memoh -d memoh + +# View database logs +docker compose logs postgres +``` + +### Port Conflicts +```bash +# Check port usage +sudo netstat -tlnp | grep :8080 +sudo netstat -tlnp | grep :80 + +# Modify port mapping in docker-compose.yml +# Example: change "80:80" to "8000:80" +``` + +### Docker Socket Permission Issues +```bash +# Add user to docker group +sudo usermod -aG docker $USER +newgrp docker + +# Check permissions +ls -la /var/run/docker.sock +``` + +## Production Deployment + +### 1. Use HTTPS + +Create `docker-compose.override.yml`: +```yaml +services: + web: + ports: + - "443:443" + volumes: + - ./ssl:/etc/nginx/ssl:ro + - ./docker/config/nginx-https.conf:/etc/nginx/conf.d/default.conf:ro +``` + +Create `docker/config/nginx-https.conf`: +```nginx +server { + listen 80; + server_name your-domain.com; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name your-domain.com; + + ssl_certificate /etc/nginx/ssl/cert.pem; + ssl_certificate_key /etc/nginx/ssl/key.pem; + + # SSL configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + # Other configurations same as docker/config/nginx.conf + # ... +} +``` + +### 2. Resource Limits + +Edit `docker-compose.yml` to add resource limits: +```yaml +services: + server: + deploy: + resources: + limits: + cpus: '2' + memory: 2G + reservations: + cpus: '1' + memory: 1G +``` + +### 3. Security Recommendations + +Production environment recommendations: +- Change all default passwords in `config.toml` +- Use strong JWT secret +- Configure firewall rules +- Use HTTPS +- Regular data backups +- Limit containerd socket access permissions +- Run services as non-root user +- Configure log rotation + +## Performance Optimization + +### PostgreSQL Optimization +Create `postgres-custom.conf`: +``` +shared_buffers = 2GB +effective_cache_size = 6GB +maintenance_work_mem = 512MB +checkpoint_completion_target = 0.9 +wal_buffers = 16MB +``` + +Mount in `docker-compose.yml`: +```yaml +postgres: + volumes: + - ./postgres-custom.conf:/etc/postgresql/postgresql.conf:ro + command: postgres -c config_file=/etc/postgresql/postgresql.conf +``` + +### Network Optimization +```yaml +networks: + memoh-network: + driver: bridge + driver_opts: + com.docker.network.driver.mtu: 1500 +``` + +## Update Application + +```bash +# Pull latest code +git pull + +# Rebuild and restart +docker compose up -d --build +``` + +## Complete Uninstall + +```bash +# Stop and remove all containers +docker compose down + +# Remove data volumes (Warning! This deletes all data) +docker compose down -v + +# Remove images +docker rmi memoh-mcp:latest +docker rmi $(docker images | grep memoh | awk '{print $3}') +``` + +## Security Considerations + +⚠️ Important Security Notes: + +1. **Docker Socket Access**: The main service container has access to the host Docker socket, which means the application can manage other containers on the host. Only run in trusted environments. +2. **Change Default Passwords**: Must change all default passwords in `config.toml` +3. **Strong JWT Secret**: Use a strong random JWT secret (generate with `openssl rand -base64 32`) +4. **Firewall**: Configure firewall to only open necessary ports +5. **HTTPS**: Use HTTPS in production +6. **Regular Backups**: Regularly backup data +7. **Updates**: Regularly update images and dependencies + +## Get Help + +- Detailed Documentation: [DOCKER_DEPLOYMENT_CN.md](DOCKER_DEPLOYMENT_CN.md) (Chinese) +- GitHub Issues: https://github.com/memohai/Memoh/issues +- Telegram Group: https://t.me/memohai +- Email: business@memoh.net + +--- + +**That's it! Deploy Memoh in minutes!** diff --git a/README.md b/README.md index cb8f7977..dde9d622 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ Last Commit Issues +
+ [Telegram Group] + [Documentation] + [Cooperation] +

@@ -43,9 +48,23 @@ Memoh Bot can distinguish and remember requests from multiple humans and bots, w Please refer to the [Roadmap Version 0.1](https://github.com/memohai/Memoh/issues/2) for more details. -## Development +## Quick Start -Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more details. +### Docker Deployment (Recommended) + +The fastest way to deploy Memoh: + +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +./deploy.sh +``` + +Visit http://localhost after deployment. See [Docker Deployment Guide](README_DOCKER.md) for details. + +### Development + +Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for development setup. ## Star History @@ -57,8 +76,6 @@ Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for more details. ---- - **LICENSE**: AGPLv3 Copyright (C) 2026 Memoh. All rights reserved. diff --git a/README_CN.md b/README_CN.md index 09f8fdc6..80ecf03c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -15,6 +15,11 @@ Last Commit Issues +
+ [Telegram 群组] + [文档] + [合作] +

@@ -43,7 +48,21 @@ Memoh Bot 能够区分并记忆来自多个人类/Bot 的请求,可在任意 详情请参阅 [Roadmap Version 0.1](https://github.com/memohai/Memoh/issues/2)。 -## 开发 +## 快速开始 + +### Docker 部署(推荐) + +最快的部署方式: + +```bash +git clone https://github.com/memohai/Memoh.git +cd Memoh +./deploy.sh +``` + +部署完成后访问 http://localhost。详见 [Docker 部署指南](README_DOCKER.md)。 + +### 开发环境 详见 [CONTRIBUTING.md](CONTRIBUTING.md)。 @@ -57,8 +76,6 @@ Memoh Bot 能够区分并记忆来自多个人类/Bot 的请求,可在任意 ---- - **LICENSE**: AGPLv3 Copyright (C) 2026 Memoh. All rights reserved. \ No newline at end of file diff --git a/assets/telegram.jpg b/assets/telegram.jpg new file mode 100644 index 00000000..5f25d87d Binary files /dev/null and b/assets/telegram.jpg differ diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..58c867ee --- /dev/null +++ b/deploy.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +set -e + +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN} Memoh Docker Compose Deployment${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" + +# Check Docker +if ! command -v docker &> /dev/null; then + echo -e "${RED}Error: Docker is not installed${NC}" + echo "Please install Docker first:" + echo " - Linux: curl -fsSL https://get.docker.com | sh" + echo " - macOS: brew install --cask docker" + echo " - Windows: https://docs.docker.com/desktop/install/windows-install/" + echo " - Official guide: https://docs.docker.com/get-docker/" + exit 1 +fi + +# Check Docker Compose +if ! docker compose version &> /dev/null; then + echo -e "${RED}Error: Docker Compose is not installed or version is too old${NC}" + echo "Docker Compose v2.0+ is required (bundled with Docker Desktop)" + echo " - Linux: sudo apt-get install docker-compose-plugin" + echo " - Or follow: https://docs.docker.com/compose/install/" + exit 1 +fi + +echo -e "${GREEN}✓ Docker and Docker Compose are installed${NC}" +echo "" + + +# Check config.toml +if [ ! -f config.toml ]; then + echo -e "${YELLOW}⚠ config.toml does not exist, creating...${NC}" + cp docker/config/config.docker.toml config.toml + echo -e "${GREEN}✓ config.toml created${NC}" + echo "" +fi + +# Build MCP image +echo -e "${GREEN}Building MCP image...${NC}" +if docker build -f docker/Dockerfile.mcp -t memoh-mcp:latest . > /dev/null 2>&1; then + echo -e "${GREEN}✓ MCP image built successfully${NC}" +else + echo -e "${YELLOW}⚠ MCP image build failed, will try to pull at runtime${NC}" +fi +echo "" + +# Start services +echo -e "${GREEN}Starting services...${NC}" +docker compose up -d + +echo "" +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN} Deployment Complete!${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" +echo "Service URLs:" +echo " - Web UI: http://localhost" +echo " - API Service: http://localhost:8080" +echo " - Agent Gateway: http://localhost:8081" +echo "" +echo "View service status:" +echo " docker compose ps" +echo "" +echo "View logs:" +echo " docker compose logs -f" +echo "" +echo "Stop services:" +echo " docker compose down" +echo "" +echo -e "${YELLOW}⚠ First startup may take 1-2 minutes, please be patient${NC}" +echo "" +echo "View detailed documentation: DEPLOYMENT.md" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..1345bc93 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,114 @@ +services: + + postgres: + image: postgres:18.1-alpine + container_name: memoh-postgres + environment: + POSTGRES_DB: memoh + POSTGRES_USER: memoh + POSTGRES_PASSWORD: memoh123 + volumes: + - postgres_data:/var/lib/postgresql/data + - ./db/migrations:/docker-entrypoint-initdb.d:ro + expose: + - "5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U memoh"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - memoh-network + + qdrant: + image: qdrant/qdrant:latest + container_name: memoh-qdrant + volumes: + - qdrant_data:/qdrant/storage + expose: + - "6333" + - "6334" + healthcheck: + test: ["CMD-SHELL", "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/6333' || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - memoh-network + + docker-cli: + image: docker:27-cli + container_name: memoh-docker-cli + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - memoh_bot_data:/var/lib/memoh/data + command: ["tail", "-f", "/dev/null"] + restart: unless-stopped + networks: + - memoh-network + + server: + build: + context: ./docker + dockerfile: Dockerfile.server + container_name: memoh-server + volumes: + - ./config.toml:/app/config.toml:ro + - /var/run/docker.sock:/var/run/docker.sock + - memoh_bot_data:/var/lib/memoh/data + ports: + - "8080:8080" + depends_on: + postgres: + condition: service_healthy + qdrant: + condition: service_healthy + restart: unless-stopped + networks: + - memoh-network + + agent: + build: + context: . + dockerfile: docker/Dockerfile.agent + container_name: memoh-agent + volumes: + - ./config.toml:/config.toml:ro + ports: + - "8081:8081" + depends_on: + - server + restart: unless-stopped + networks: + - memoh-network + + web: + build: + context: . + dockerfile: docker/Dockerfile.web + args: + - VITE_API_URL=http://localhost:8080 + - VITE_AGENT_URL=http://localhost:8081 + container_name: memoh-web + ports: + - "80:80" + depends_on: + - server + - agent + restart: unless-stopped + networks: + - memoh-network + +volumes: + postgres_data: + driver: local + qdrant_data: + driver: local + memoh_bot_data: + driver: local + +networks: + memoh-network: + driver: bridge diff --git a/docker/Dockerfile.agent b/docker/Dockerfile.agent new file mode 100644 index 00000000..da4c4cef --- /dev/null +++ b/docker/Dockerfile.agent @@ -0,0 +1,28 @@ +FROM oven/bun:1 AS builder + +WORKDIR /build + +COPY agent/package.json agent/bun.lock* ./ + +RUN bun install + +COPY agent/ ./ + +RUN bun run build --external jsdom + +FROM oven/bun:1-alpine + +WORKDIR /app + +RUN apk add --no-cache ca-certificates wget + +COPY --from=builder /build/dist /app/dist +COPY --from=builder /build/node_modules /app/node_modules +COPY --from=builder /build/package.json /app/package.json + +EXPOSE 8081 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8081/health || exit 1 + +CMD ["bun", "run", "dist/index.js"] diff --git a/cmd/mcp/Dockerfile b/docker/Dockerfile.mcp similarity index 100% rename from cmd/mcp/Dockerfile rename to docker/Dockerfile.mcp diff --git a/docker/Dockerfile.server b/docker/Dockerfile.server new file mode 100644 index 00000000..e0d68061 --- /dev/null +++ b/docker/Dockerfile.server @@ -0,0 +1,31 @@ +FROM golang:1.25-alpine AS builder + +WORKDIR /build + +RUN apk add --no-cache git make + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ + go build -trimpath -ldflags "-s -w" \ + -o memoh-server ./cmd/agent/main.go + +FROM alpine:latest + +WORKDIR /app + +RUN apk add --no-cache ca-certificates tzdata wget + +COPY --from=builder /build/memoh-server /app/memoh-server + +RUN mkdir -p /var/lib/memoh/data + +EXPOSE 8080 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 + +CMD ["/app/memoh-server"] diff --git a/docker/Dockerfile.web b/docker/Dockerfile.web new file mode 100644 index 00000000..c1532a7a --- /dev/null +++ b/docker/Dockerfile.web @@ -0,0 +1,33 @@ +FROM node:25-alpine AS builder + +WORKDIR /build + +RUN npm install -g pnpm@10 + +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ + +COPY packages ./packages + +RUN pnpm install + +ARG VITE_API_URL=http://localhost:8080 +ARG VITE_AGENT_URL=http://localhost:8081 + +ENV VITE_API_URL=$VITE_API_URL +ENV VITE_AGENT_URL=$VITE_AGENT_URL + +WORKDIR /build/packages/web +RUN pnpm build + +FROM nginx:alpine + +COPY --from=builder /build/packages/web/dist /usr/share/nginx/html + +COPY docker/config/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/config/config.docker.toml b/docker/config/config.docker.toml new file mode 100644 index 00000000..3ea7e9b7 --- /dev/null +++ b/docker/config/config.docker.toml @@ -0,0 +1,54 @@ +## Service configuration +[log] +level = "info" +format = "text" + +[server] +addr = ":8080" + +## Admin +[admin] +username = "admin" +password = "admin123" +email = "admin@memoh.local" + +## Auth configuration +[auth] +jwt_secret = "YZq8kXrW5dFpNt9mLxQvHbRjKsMnOePw" +jwt_expires_in = "168h" + +## Docker configuration +[containerd] +socket_path = "unix:///var/run/docker.sock" +namespace = "default" + +[mcp] +busybox_image = "memoh-mcp:latest" +snapshotter = "overlayfs" +data_root = "/var/lib/memoh/data" +data_mount = "/data" + +## Postgres configuration +[postgres] +host = "postgres" +port = 5432 +user = "memoh" +password = "memoh123" +database = "memoh" +sslmode = "disable" + +## Qdrant configuration +[qdrant] +base_url = "http://qdrant:6334" +api_key = "" +collection = "memory" +timeout_seconds = 10 + +## Agent Gateway +[agent_gateway] +host = "agent" +port = 8081 + +[brave] +api_key = "" +base_url = "https://api.search.brave.com/res/v1/" diff --git a/docker/config/nginx.conf b/docker/config/nginx.conf new file mode 100644 index 00000000..b89ba890 --- /dev/null +++ b/docker/config/nginx.conf @@ -0,0 +1,64 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + # Gzip 压缩 + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript; + + # 前端路由 + location / { + try_files $uri $uri/ /index.html; + } + + # API 代理 + location /api/ { + proxy_pass http://memoh-server:8080/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # Agent Gateway 代理 + location /agent/ { + proxy_pass http://memoh-agent:8081/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # 静态资源缓存 + location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # 安全头 + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; +} diff --git a/eslint.config.mjs b/eslint.config.mjs index 732ab0fd..8f9c5b64 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -6,7 +6,7 @@ import vue from 'eslint-plugin-vue' export default [ ...tseslint.configs.recommended, ...vue.configs['flat/recommended'], - { ignores: ['**/node_modules/**', '**/dist/**'] }, + { ignores: ['**/node_modules/**', '**/dist/**', 'packages/sdk/src/**'] }, { files: ['packages/**/*.{js,jsx,ts,tsx}', 'agent/**/*.{js,jsx,ts,tsx}'], languageOptions: { diff --git a/internal/bots/types.go b/internal/bots/types.go index 7a9babf5..6d237746 100644 --- a/internal/bots/types.go +++ b/internal/bots/types.go @@ -7,15 +7,15 @@ import ( // Bot represents a bot entity. type Bot struct { - ID string `json:"id"` - OwnerUserID string `json:"owner_user_id"` - Type string `json:"type"` - DisplayName string `json:"display_name"` + ID string `json:"id" validate:"required"` + OwnerUserID string `json:"owner_user_id" validate:"required"` + Type string `json:"type" validate:"required"` + DisplayName string `json:"display_name" validate:"required"` AvatarURL string `json:"avatar_url,omitempty"` - IsActive bool `json:"is_active"` + IsActive bool `json:"is_active" validate:"required"` Metadata map[string]any `json:"metadata,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + CreatedAt time.Time `json:"created_at" validate:"required"` + UpdatedAt time.Time `json:"updated_at" validate:"required"` } // BotMember represents a bot membership record. @@ -56,7 +56,7 @@ type UpsertMemberRequest struct { // ListBotsResponse wraps a list of bots. type ListBotsResponse struct { - Items []Bot `json:"items"` + Items []Bot `json:"items" validate:"required"` } // ListMembersResponse wraps a list of bot members. diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go index dfb4503d..f953777a 100644 --- a/internal/handlers/auth.go +++ b/internal/handlers/auth.go @@ -21,18 +21,18 @@ type AuthHandler struct { } type LoginRequest struct { - Username string `json:"username"` - Password string `json:"password"` + Username string `json:"username" validate:"required"` + Password string `json:"password" validate:"required"` } type LoginResponse struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresAt string `json:"expires_at"` - UserID string `json:"user_id"` - Role string `json:"role"` - DisplayName string `json:"display_name"` - Username string `json:"username"` + AccessToken string `json:"access_token" validate:"required"` + TokenType string `json:"token_type" validate:"required"` + ExpiresAt string `json:"expires_at" validate:"required"` + UserID string `json:"user_id" validate:"required"` + Role string `json:"role" validate:"required"` + DisplayName string `json:"display_name" validate:"required"` + Username string `json:"username" validate:"required"` } func NewAuthHandler(log *slog.Logger, accountService *accounts.Service, jwtSecret string, expiresIn time.Duration) *AuthHandler { diff --git a/internal/handlers/channel.go b/internal/handlers/channel.go index 9f8ec869..1fa423b2 100644 --- a/internal/handlers/channel.go +++ b/internal/handlers/channel.go @@ -94,11 +94,11 @@ func (h *ChannelHandler) UpsertChannelIdentityConfig(c echo.Context) error { } type ChannelMeta struct { - Type string `json:"type"` - DisplayName string `json:"display_name"` + Type string `json:"type" validate:"required"` + DisplayName string `json:"display_name" validate:"required"` Configless bool `json:"configless"` - Capabilities channel.ChannelCapabilities `json:"capabilities"` - ConfigSchema channel.ConfigSchema `json:"config_schema"` + Capabilities channel.ChannelCapabilities `json:"capabilities" validate:"required"` + ConfigSchema channel.ConfigSchema `json:"config_schema" validate:"required"` UserConfigSchema channel.ConfigSchema `json:"user_config_schema"` TargetSpec channel.TargetSpec `json:"target_spec"` } diff --git a/internal/handlers/mcp.go b/internal/handlers/mcp.go index 784150d4..6434f1c9 100644 --- a/internal/handlers/mcp.go +++ b/internal/handlers/mcp.go @@ -46,6 +46,7 @@ func (h *MCPHandler) Register(e *echo.Echo) { // @Summary List MCP connections // @Description List MCP connections for a bot // @Tags mcp +// @Param bot_id path string true "Bot ID" // @Success 200 {object} mcp.ListResponse // @Failure 400 {object} ErrorResponse // @Failure 403 {object} ErrorResponse @@ -75,6 +76,7 @@ func (h *MCPHandler) List(c echo.Context) error { // @Summary Create MCP connection // @Description Create a MCP connection for a bot // @Tags mcp +// @Param bot_id path string true "Bot ID" // @Param payload body mcp.UpsertRequest true "MCP payload" // @Success 201 {object} mcp.Connection // @Failure 400 {object} ErrorResponse @@ -109,6 +111,7 @@ func (h *MCPHandler) Create(c echo.Context) error { // @Summary Get MCP connection // @Description Get a MCP connection by ID // @Tags mcp +// @Param bot_id path string true "Bot ID" // @Param id path string true "MCP ID" // @Success 200 {object} mcp.Connection // @Failure 400 {object} ErrorResponse @@ -146,6 +149,7 @@ func (h *MCPHandler) Get(c echo.Context) error { // @Summary Update MCP connection // @Description Update a MCP connection by ID // @Tags mcp +// @Param bot_id path string true "Bot ID" // @Param id path string true "MCP ID" // @Param payload body mcp.UpsertRequest true "MCP payload" // @Success 200 {object} mcp.Connection @@ -188,6 +192,7 @@ func (h *MCPHandler) Update(c echo.Context) error { // @Summary Delete MCP connection // @Description Delete a MCP connection by ID // @Tags mcp +// @Param bot_id path string true "Bot ID" // @Param id path string true "MCP ID" // @Success 204 "No Content" // @Failure 400 {object} ErrorResponse diff --git a/internal/handlers/schedule.go b/internal/handlers/schedule.go index 42643408..75df5269 100644 --- a/internal/handlers/schedule.go +++ b/internal/handlers/schedule.go @@ -45,6 +45,7 @@ func (h *ScheduleHandler) Register(e *echo.Echo) { // @Summary Create schedule // @Description Create a schedule for current user // @Tags schedule +// @Param bot_id path string true "Bot ID" // @Param payload body schedule.CreateRequest true "Schedule payload" // @Success 201 {object} schedule.Schedule // @Failure 400 {object} ErrorResponse @@ -77,6 +78,7 @@ func (h *ScheduleHandler) Create(c echo.Context) error { // @Summary List schedules // @Description List schedules for current user // @Tags schedule +// @Param bot_id path string true "Bot ID" // @Success 200 {object} schedule.ListResponse // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse @@ -104,6 +106,7 @@ func (h *ScheduleHandler) List(c echo.Context) error { // @Summary Get schedule // @Description Get a schedule by ID // @Tags schedule +// @Param bot_id path string true "Bot ID" // @Param id path string true "Schedule ID" // @Success 200 {object} schedule.Schedule // @Failure 400 {object} ErrorResponse @@ -140,6 +143,7 @@ func (h *ScheduleHandler) Get(c echo.Context) error { // @Summary Update schedule // @Description Update a schedule by ID // @Tags schedule +// @Param bot_id path string true "Bot ID" // @Param id path string true "Schedule ID" // @Param payload body schedule.UpdateRequest true "Schedule payload" // @Success 200 {object} schedule.Schedule @@ -184,6 +188,7 @@ func (h *ScheduleHandler) Update(c echo.Context) error { // @Summary Delete schedule // @Description Delete a schedule by ID // @Tags schedule +// @Param bot_id path string true "Bot ID" // @Param id path string true "Schedule ID" // @Success 204 "No Content" // @Failure 400 {object} ErrorResponse diff --git a/internal/handlers/settings.go b/internal/handlers/settings.go index 7c3d57d0..5e83d122 100644 --- a/internal/handlers/settings.go +++ b/internal/handlers/settings.go @@ -44,6 +44,7 @@ func (h *SettingsHandler) Register(e *echo.Echo) { // @Summary Get user settings // @Description Get agent settings for current user // @Tags settings +// @Param bot_id path string true "Bot ID" // @Success 200 {object} settings.Settings // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse @@ -71,6 +72,7 @@ func (h *SettingsHandler) Get(c echo.Context) error { // @Summary Update user settings // @Description Update or create agent settings for current user // @Tags settings +// @Param bot_id path string true "Bot ID" // @Param payload body settings.UpsertRequest true "Settings payload" // @Success 200 {object} settings.Settings // @Failure 400 {object} ErrorResponse @@ -107,6 +109,7 @@ func (h *SettingsHandler) Upsert(c echo.Context) error { // @Summary Delete user settings // @Description Remove agent settings for current user // @Tags settings +// @Param bot_id path string true "Bot ID" // @Success 204 "No Content" // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse diff --git a/internal/handlers/subagent.go b/internal/handlers/subagent.go index 40d86c15..67c734db 100644 --- a/internal/handlers/subagent.go +++ b/internal/handlers/subagent.go @@ -50,6 +50,7 @@ func (h *SubagentHandler) Register(e *echo.Echo) { // @Summary Create subagent // @Description Create a subagent for current user // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param payload body subagent.CreateRequest true "Subagent payload" // @Success 201 {object} subagent.Subagent // @Failure 400 {object} ErrorResponse @@ -82,6 +83,7 @@ func (h *SubagentHandler) Create(c echo.Context) error { // @Summary List subagents // @Description List subagents for current user // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Success 200 {object} subagent.ListResponse // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse @@ -109,6 +111,7 @@ func (h *SubagentHandler) List(c echo.Context) error { // @Summary Get subagent // @Description Get a subagent by ID // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Success 200 {object} subagent.Subagent // @Failure 400 {object} ErrorResponse @@ -145,6 +148,7 @@ func (h *SubagentHandler) Get(c echo.Context) error { // @Summary Update subagent // @Description Update a subagent by ID // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Param payload body subagent.UpdateRequest true "Subagent payload" // @Success 200 {object} subagent.Subagent @@ -190,6 +194,7 @@ func (h *SubagentHandler) Update(c echo.Context) error { // @Summary Delete subagent // @Description Delete a subagent by ID // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Success 204 "No Content" // @Failure 400 {object} ErrorResponse @@ -229,6 +234,7 @@ func (h *SubagentHandler) Delete(c echo.Context) error { // @Summary Get subagent context // @Description Get a subagent's message context // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Success 200 {object} subagent.ContextResponse // @Failure 400 {object} ErrorResponse @@ -265,6 +271,7 @@ func (h *SubagentHandler) GetContext(c echo.Context) error { // @Summary Update subagent context // @Description Update a subagent's message context // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Param payload body subagent.UpdateContextRequest true "Context payload" // @Success 200 {object} subagent.ContextResponse @@ -310,6 +317,7 @@ func (h *SubagentHandler) UpdateContext(c echo.Context) error { // @Summary Get subagent skills // @Description Get a subagent's skills // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Success 200 {object} subagent.SkillsResponse // @Failure 400 {object} ErrorResponse @@ -346,6 +354,7 @@ func (h *SubagentHandler) GetSkills(c echo.Context) error { // @Summary Update subagent skills // @Description Replace a subagent's skills // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Param payload body subagent.UpdateSkillsRequest true "Skills payload" // @Success 200 {object} subagent.SkillsResponse @@ -391,6 +400,7 @@ func (h *SubagentHandler) UpdateSkills(c echo.Context) error { // @Summary Add subagent skills // @Description Add skills to a subagent // @Tags subagent +// @Param bot_id path string true "Bot ID" // @Param id path string true "Subagent ID" // @Param payload body subagent.AddSkillsRequest true "Skills payload" // @Success 200 {object} subagent.SkillsResponse diff --git a/internal/handlers/swagger.go b/internal/handlers/swagger.go index 2900ae1a..4d4dec89 100644 --- a/internal/handlers/swagger.go +++ b/internal/handlers/swagger.go @@ -12,7 +12,7 @@ import ( "github.com/labstack/echo/v4" ) -//go:generate go run github.com/swaggo/swag/cmd/swag@latest init -g swagger.go -o ../../docs --parseDependency --parseInternal +//go:generate go run github.com/swaggo/swag/cmd/swag@latest init -g swagger.go -o ../../spec --parseDependency --parseInternal var ( swaggerSpec []byte @@ -36,7 +36,7 @@ func (h *SwaggerHandler) Register(e *echo.Echo) { func (h *SwaggerHandler) Spec(c echo.Context) error { swaggerOnce.Do(func() { - swaggerSpec, swaggerErr = os.ReadFile("docs/swagger.json") + swaggerSpec, swaggerErr = os.ReadFile("spec/swagger.json") }) if swaggerErr != nil { return echo.NewHTTPError(http.StatusInternalServerError, swaggerErr.Error()) diff --git a/internal/mcp/connections.go b/internal/mcp/connections.go index f08ba91d..0a829b1d 100644 --- a/internal/mcp/connections.go +++ b/internal/mcp/connections.go @@ -14,14 +14,14 @@ import ( // Connection represents a stored MCP connection for a bot. type Connection struct { - ID string `json:"id"` - BotID string `json:"bot_id"` - Name string `json:"name"` - Type string `json:"type"` - Config map[string]any `json:"config"` - Active bool `json:"active"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID string `json:"id" validate:"required"` + BotID string `json:"bot_id" validate:"required"` + Name string `json:"name" validate:"required"` + Type string `json:"type" validate:"required"` + Config map[string]any `json:"config" validate:"required"` + Active bool `json:"active" validate:"required"` + CreatedAt time.Time `json:"created_at" validate:"required"` + UpdatedAt time.Time `json:"updated_at" validate:"required"` } // UpsertRequest is the payload for creating or updating MCP connections. diff --git a/internal/models/types.go b/internal/models/types.go index c0ef4df2..c8252bb4 100644 --- a/internal/models/types.go +++ b/internal/models/types.go @@ -32,13 +32,13 @@ const ( ) type Model struct { - ModelID string `json:"model_id"` - Name string `json:"name"` - LlmProviderID string `json:"llm_provider_id"` - IsMultimodal bool `json:"is_multimodal"` - Input []string `json:"input"` - Type ModelType `json:"type"` - Dimensions int `json:"dimensions"` + ModelID string `json:"model_id" validate:"required"` + Name string `json:"name" validate:"required"` + LlmProviderID string `json:"llm_provider_id" validate:"required"` + IsMultimodal bool `json:"is_multimodal"` + Input []string `json:"input"` + Type ModelType `json:"type" validate:"required"` + Dimensions int `json:"dimensions"` } func (m *Model) Validate() error { diff --git a/internal/providers/types.go b/internal/providers/types.go index 4eec664e..e2556f64 100644 --- a/internal/providers/types.go +++ b/internal/providers/types.go @@ -33,14 +33,14 @@ type UpdateRequest struct { // GetResponse represents the response for getting a provider type GetResponse struct { - ID string `json:"id"` - Name string `json:"name"` - ClientType string `json:"client_type"` - BaseURL string `json:"base_url"` + ID string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + ClientType string `json:"client_type" validate:"required"` + BaseURL string `json:"base_url" validate:"required"` APIKey string `json:"api_key,omitempty"` // masked in response Metadata map[string]any `json:"metadata,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + CreatedAt time.Time `json:"created_at" validate:"required"` + UpdatedAt time.Time `json:"updated_at" validate:"required"` } // ListResponse represents the response for listing providers diff --git a/internal/settings/types.go b/internal/settings/types.go index f750f8ff..9950566c 100644 --- a/internal/settings/types.go +++ b/internal/settings/types.go @@ -6,12 +6,12 @@ const ( ) type Settings struct { - ChatModelID string `json:"chat_model_id"` - MemoryModelID string `json:"memory_model_id"` - EmbeddingModelID string `json:"embedding_model_id"` - MaxContextLoadTime int `json:"max_context_load_time"` - Language string `json:"language"` - AllowGuest bool `json:"allow_guest"` + ChatModelID string `json:"chat_model_id" validate:"required"` + MemoryModelID string `json:"memory_model_id" validate:"required"` + EmbeddingModelID string `json:"embedding_model_id" validate:"required"` + MaxContextLoadTime int `json:"max_context_load_time" validate:"required"` + Language string `json:"language" validate:"required"` + AllowGuest bool `json:"allow_guest" validate:"required"` } type UpsertRequest struct { diff --git a/mise.toml b/mise.toml index 5d94ffcb..544089b7 100644 --- a/mise.toml +++ b/mise.toml @@ -11,6 +11,8 @@ bun = "latest" pnpm = "10" # sqlc for sql management sqlc = "latest" +# typos for spell check +typos = "latest" # Lima for macOS lima = { version = "system", platform = "darwin" } @@ -46,6 +48,11 @@ run = "scripts/containerd-install.sh" description = "Generate Swagger documentation" run = "cd internal/handlers && go generate" +[tasks.sdk-generate] +description = "Generate SDK code" +run = "pnpm run generate-sdk" +depends = ["//:swagger-generate"] + [tasks.sqlc-generate] description = "Generate SQL code" run = "sqlc generate" @@ -88,6 +95,7 @@ run = "scripts/compile-mcp.sh" description = "Start development environment" depends = [ "//:swagger-generate", + "//:sdk-generate", "//agent:dev", "//cmd/agent:start", "//packages/web:dev", diff --git a/openapi-ts.config.ts b/openapi-ts.config.ts new file mode 100644 index 00000000..22186f88 --- /dev/null +++ b/openapi-ts.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig({ + input: './spec/swagger.json', + output: 'packages/sdk/src', + plugins: [ + '@hey-api/typescript', + { + name: '@hey-api/transformers', + dates: true, + bigInt: true, + }, + { + name: '@hey-api/sdk', + transformer: true + }, + '@hey-api/client-fetch', + '@pinia/colada', + ], +}) \ No newline at end of file diff --git a/package.json b/package.json index 52c506a0..bb2a4ca4 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "agent:dev": "pnpm --filter @memoh/agent-gateway dev", "agent:build": "pnpm --filter @memoh/agent-gateway build", "agent:start": "pnpm --filter @memoh/agent-gateway start", + "generate-sdk": "openapi-ts", "lint": "eslint .", "lint:fix": "eslint . --fix", "test": "vitest" @@ -20,6 +21,7 @@ "author": "", "license": "ISC", "devDependencies": { + "@hey-api/openapi-ts": "0.92.3", "@types/node": "^25.0.3", "eslint": "^9.39.2", "eslint-plugin-vue": "^10.6.2", @@ -38,5 +40,5 @@ "@algolia/client-search" ] } - } + } } diff --git a/packages/cli/package.json b/packages/cli/package.json index f2d9894f..986bf916 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -18,7 +18,6 @@ }, "dependencies": { "@elysiajs/eden": "^1.4.6", - "@memoh/shared": "workspace:*", "elysia": "latest", "commander": "^12.1.0", "chalk": "^5.4.1", diff --git a/packages/sdk/README.md b/packages/sdk/README.md new file mode 100644 index 00000000..3230f848 --- /dev/null +++ b/packages/sdk/README.md @@ -0,0 +1 @@ +# @memoh/sdk diff --git a/packages/sdk/package.json b/packages/sdk/package.json new file mode 100644 index 00000000..48dedfb9 --- /dev/null +++ b/packages/sdk/package.json @@ -0,0 +1,23 @@ +{ + "name": "@memoh/sdk", + "version": "1.0.0", + "description": "", + "exports": { + ".": "./src/index.ts", + "./client": "./src/client.gen.ts", + "./colada": "./src/@pinia/colada.gen.ts" + }, + "main": "index.js", + "scripts": { + + }, + "packageManager": "pnpm@10.27.0", + "peerDependencies": { + "@pinia/colada": ">=0.21.0" + }, + "peerDependenciesMeta": { + "@pinia/colada": { + "optional": true + } + } +} diff --git a/packages/sdk/src/@pinia/colada.gen.ts b/packages/sdk/src/@pinia/colada.gen.ts new file mode 100644 index 00000000..acb165a5 --- /dev/null +++ b/packages/sdk/src/@pinia/colada.gen.ts @@ -0,0 +1,1818 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { type _JSONValue, defineQueryOptions, type UseMutationOptions } from '@pinia/colada'; + +import { serializeQueryKeyValue } from '../client'; +import { client } from '../client.gen'; +import { deleteBotsByBotIdContainer, deleteBotsByBotIdContainerFs, deleteBotsByBotIdContainerSkills, deleteBotsByBotIdHistory, deleteBotsByBotIdHistoryById, deleteBotsByBotIdMcpById, deleteBotsByBotIdMemoryMemories, deleteBotsByBotIdMemoryMemoriesByMemoryId, deleteBotsByBotIdScheduleById, deleteBotsByBotIdSettings, deleteBotsByBotIdSubagentsById, deleteBotsById, deleteBotsByIdMembersByUserId, deleteModelsById, deleteModelsModelByModelId, deleteProvidersById, getBots, getBotsByBotIdContainer, getBotsByBotIdContainerFs, getBotsByBotIdContainerFsFile, getBotsByBotIdContainerFsStat, getBotsByBotIdContainerFsUsage, getBotsByBotIdContainerSkills, getBotsByBotIdContainerSnapshots, getBotsByBotIdHistory, getBotsByBotIdHistoryById, getBotsByBotIdMcp, getBotsByBotIdMcpById, getBotsByBotIdMemoryMemories, getBotsByBotIdMemoryMemoriesByMemoryId, getBotsByBotIdSchedule, getBotsByBotIdScheduleById, getBotsByBotIdSettings, getBotsByBotIdSubagents, getBotsByBotIdSubagentsById, getBotsByBotIdSubagentsByIdContext, getBotsByBotIdSubagentsByIdSkills, getBotsById, getBotsByIdChannelByPlatform, getBotsByIdMembers, getChannels, getChannelsByPlatform, getModels, getModelsById, getModelsCount, getModelsModelByModelId, getProviders, getProvidersById, getProvidersByIdModels, getProvidersCount, getProvidersNameByName, getUsers, getUsersById, getUsersMe, getUsersMeChannelsByPlatform, type Options, postAuthLogin, postBots, postBotsByBotIdChat, postBotsByBotIdChatStream, postBotsByBotIdContainer, postBotsByBotIdContainerFsDir, postBotsByBotIdContainerFsFile, postBotsByBotIdContainerFsMcp, postBotsByBotIdContainerFsUpload, postBotsByBotIdContainerSkills, postBotsByBotIdContainerSnapshots, postBotsByBotIdContainerStart, postBotsByBotIdContainerStop, postBotsByBotIdHistory, postBotsByBotIdMcp, postBotsByBotIdMcpStdio, postBotsByBotIdMcpStdioBySessionId, postBotsByBotIdMemoryAdd, postBotsByBotIdMemoryEmbed, postBotsByBotIdMemorySearch, postBotsByBotIdMemoryUpdate, postBotsByBotIdSchedule, postBotsByBotIdSettings, postBotsByBotIdSubagents, postBotsByBotIdSubagentsByIdSkills, postBotsByIdChannelByPlatformSend, postBotsByIdChannelByPlatformSendSession, postEmbeddings, postModels, postModelsEnable, postProviders, postUsers, putBotsByBotIdMcpById, putBotsByBotIdScheduleById, putBotsByBotIdSettings, putBotsByBotIdSubagentsById, putBotsByBotIdSubagentsByIdContext, putBotsByBotIdSubagentsByIdSkills, putBotsById, putBotsByIdChannelByPlatform, putBotsByIdMembers, putBotsByIdOwner, putModelsById, putModelsModelByModelId, putProvidersById, putUsersById, putUsersByIdPassword, putUsersMe, putUsersMeChannelsByPlatform, putUsersMePassword } from '../sdk.gen'; +import type { DeleteBotsByBotIdContainerData, DeleteBotsByBotIdContainerError, DeleteBotsByBotIdContainerFsData, DeleteBotsByBotIdContainerFsError, DeleteBotsByBotIdContainerFsResponse, DeleteBotsByBotIdContainerSkillsData, DeleteBotsByBotIdContainerSkillsError, DeleteBotsByBotIdContainerSkillsResponse, DeleteBotsByBotIdHistoryByIdData, DeleteBotsByBotIdHistoryByIdError, DeleteBotsByBotIdHistoryData, DeleteBotsByBotIdHistoryError, DeleteBotsByBotIdMcpByIdData, DeleteBotsByBotIdMcpByIdError, DeleteBotsByBotIdMemoryMemoriesByMemoryIdData, DeleteBotsByBotIdMemoryMemoriesByMemoryIdError, DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponse, DeleteBotsByBotIdMemoryMemoriesData, DeleteBotsByBotIdMemoryMemoriesError, DeleteBotsByBotIdMemoryMemoriesResponse, DeleteBotsByBotIdScheduleByIdData, DeleteBotsByBotIdScheduleByIdError, DeleteBotsByBotIdSettingsData, DeleteBotsByBotIdSettingsError, DeleteBotsByBotIdSubagentsByIdData, DeleteBotsByBotIdSubagentsByIdError, DeleteBotsByIdData, DeleteBotsByIdError, DeleteBotsByIdMembersByUserIdData, DeleteBotsByIdMembersByUserIdError, DeleteModelsByIdData, DeleteModelsByIdError, DeleteModelsModelByModelIdData, DeleteModelsModelByModelIdError, DeleteProvidersByIdData, DeleteProvidersByIdError, GetBotsByBotIdContainerData, GetBotsByBotIdContainerFsData, GetBotsByBotIdContainerFsFileData, GetBotsByBotIdContainerFsStatData, GetBotsByBotIdContainerFsUsageData, GetBotsByBotIdContainerSkillsData, GetBotsByBotIdContainerSnapshotsData, GetBotsByBotIdHistoryByIdData, GetBotsByBotIdHistoryData, GetBotsByBotIdMcpByIdData, GetBotsByBotIdMcpData, GetBotsByBotIdMemoryMemoriesByMemoryIdData, GetBotsByBotIdMemoryMemoriesData, GetBotsByBotIdScheduleByIdData, GetBotsByBotIdScheduleData, GetBotsByBotIdSettingsData, GetBotsByBotIdSubagentsByIdContextData, GetBotsByBotIdSubagentsByIdData, GetBotsByBotIdSubagentsByIdSkillsData, GetBotsByBotIdSubagentsData, GetBotsByIdChannelByPlatformData, GetBotsByIdData, GetBotsByIdMembersData, GetBotsData, GetChannelsByPlatformData, GetChannelsData, GetModelsByIdData, GetModelsCountData, GetModelsData, GetModelsModelByModelIdData, GetProvidersByIdData, GetProvidersByIdModelsData, GetProvidersCountData, GetProvidersData, GetProvidersNameByNameData, GetUsersByIdData, GetUsersData, GetUsersMeChannelsByPlatformData, GetUsersMeData, PostAuthLoginData, PostAuthLoginError, PostAuthLoginResponse, PostBotsByBotIdChatData, PostBotsByBotIdChatError, PostBotsByBotIdChatResponse, PostBotsByBotIdChatStreamData, PostBotsByBotIdChatStreamError, PostBotsByBotIdChatStreamResponse, PostBotsByBotIdContainerData, PostBotsByBotIdContainerError, PostBotsByBotIdContainerFsDirData, PostBotsByBotIdContainerFsDirError, PostBotsByBotIdContainerFsDirResponse, PostBotsByBotIdContainerFsFileData, PostBotsByBotIdContainerFsFileError, PostBotsByBotIdContainerFsFileResponse, PostBotsByBotIdContainerFsMcpData, PostBotsByBotIdContainerFsMcpError, PostBotsByBotIdContainerFsMcpResponse, PostBotsByBotIdContainerFsUploadData, PostBotsByBotIdContainerFsUploadError, PostBotsByBotIdContainerFsUploadResponse, PostBotsByBotIdContainerResponse, PostBotsByBotIdContainerSkillsData, PostBotsByBotIdContainerSkillsError, PostBotsByBotIdContainerSkillsResponse, PostBotsByBotIdContainerSnapshotsData, PostBotsByBotIdContainerSnapshotsError, PostBotsByBotIdContainerSnapshotsResponse, PostBotsByBotIdContainerStartData, PostBotsByBotIdContainerStartError, PostBotsByBotIdContainerStartResponse, PostBotsByBotIdContainerStopData, PostBotsByBotIdContainerStopError, PostBotsByBotIdContainerStopResponse, PostBotsByBotIdHistoryData, PostBotsByBotIdHistoryError, PostBotsByBotIdHistoryResponse, PostBotsByBotIdMcpData, PostBotsByBotIdMcpError, PostBotsByBotIdMcpResponse, PostBotsByBotIdMcpStdioBySessionIdData, PostBotsByBotIdMcpStdioBySessionIdError, PostBotsByBotIdMcpStdioBySessionIdResponse, PostBotsByBotIdMcpStdioData, PostBotsByBotIdMcpStdioError, PostBotsByBotIdMcpStdioResponse, PostBotsByBotIdMemoryAddData, PostBotsByBotIdMemoryAddError, PostBotsByBotIdMemoryAddResponse, PostBotsByBotIdMemoryEmbedData, PostBotsByBotIdMemoryEmbedError, PostBotsByBotIdMemoryEmbedResponse, PostBotsByBotIdMemorySearchData, PostBotsByBotIdMemorySearchError, PostBotsByBotIdMemorySearchResponse, PostBotsByBotIdMemoryUpdateData, PostBotsByBotIdMemoryUpdateError, PostBotsByBotIdMemoryUpdateResponse, PostBotsByBotIdScheduleData, PostBotsByBotIdScheduleError, PostBotsByBotIdScheduleResponse, PostBotsByBotIdSettingsData, PostBotsByBotIdSettingsError, PostBotsByBotIdSettingsResponse, PostBotsByBotIdSubagentsByIdSkillsData, PostBotsByBotIdSubagentsByIdSkillsError, PostBotsByBotIdSubagentsByIdSkillsResponse, PostBotsByBotIdSubagentsData, PostBotsByBotIdSubagentsError, PostBotsByBotIdSubagentsResponse, PostBotsByIdChannelByPlatformSendData, PostBotsByIdChannelByPlatformSendError, PostBotsByIdChannelByPlatformSendResponse, PostBotsByIdChannelByPlatformSendSessionData, PostBotsByIdChannelByPlatformSendSessionError, PostBotsByIdChannelByPlatformSendSessionResponse, PostBotsData, PostBotsError, PostBotsResponse, PostEmbeddingsData, PostEmbeddingsError, PostEmbeddingsResponse, PostModelsData, PostModelsEnableData, PostModelsEnableError, PostModelsEnableResponse, PostModelsError, PostModelsResponse, PostProvidersData, PostProvidersError, PostProvidersResponse, PostUsersData, PostUsersError, PostUsersResponse, PutBotsByBotIdMcpByIdData, PutBotsByBotIdMcpByIdError, PutBotsByBotIdMcpByIdResponse, PutBotsByBotIdScheduleByIdData, PutBotsByBotIdScheduleByIdError, PutBotsByBotIdScheduleByIdResponse, PutBotsByBotIdSettingsData, PutBotsByBotIdSettingsError, PutBotsByBotIdSettingsResponse, PutBotsByBotIdSubagentsByIdContextData, PutBotsByBotIdSubagentsByIdContextError, PutBotsByBotIdSubagentsByIdContextResponse, PutBotsByBotIdSubagentsByIdData, PutBotsByBotIdSubagentsByIdError, PutBotsByBotIdSubagentsByIdResponse, PutBotsByBotIdSubagentsByIdSkillsData, PutBotsByBotIdSubagentsByIdSkillsError, PutBotsByBotIdSubagentsByIdSkillsResponse, PutBotsByIdChannelByPlatformData, PutBotsByIdChannelByPlatformError, PutBotsByIdChannelByPlatformResponse, PutBotsByIdData, PutBotsByIdError, PutBotsByIdMembersData, PutBotsByIdMembersError, PutBotsByIdMembersResponse, PutBotsByIdOwnerData, PutBotsByIdOwnerError, PutBotsByIdOwnerResponse, PutBotsByIdResponse, PutModelsByIdData, PutModelsByIdError, PutModelsByIdResponse, PutModelsModelByModelIdData, PutModelsModelByModelIdError, PutModelsModelByModelIdResponse, PutProvidersByIdData, PutProvidersByIdError, PutProvidersByIdResponse, PutUsersByIdData, PutUsersByIdError, PutUsersByIdPasswordData, PutUsersByIdPasswordError, PutUsersByIdResponse, PutUsersMeChannelsByPlatformData, PutUsersMeChannelsByPlatformError, PutUsersMeChannelsByPlatformResponse, PutUsersMeData, PutUsersMeError, PutUsersMePasswordData, PutUsersMePasswordError, PutUsersMeResponse } from '../types.gen'; + +/** + * Login + * + * Validate user credentials and issue a JWT + */ +export const postAuthLoginMutation = (options?: Partial>): UseMutationOptions, PostAuthLoginError> => ({ + mutation: async (vars) => { + const { data } = await postAuthLogin({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export type QueryKey = [ + Pick & { + _id: string; + baseUrl?: _JSONValue; + body?: _JSONValue; + query?: _JSONValue; + tags?: _JSONValue; + } +]; + +const createQueryKey = (id: string, options?: TOptions, tags?: ReadonlyArray): [ + QueryKey[0] +] => { + const params: QueryKey[0] = { _id: id, baseUrl: options?.baseUrl || (options?.client ?? client).getConfig().baseUrl } as QueryKey[0]; + if (tags) { + params.tags = tags as unknown as _JSONValue; + } + if (options?.body !== undefined) { + const normalizedBody = serializeQueryKeyValue(options.body); + if (normalizedBody !== undefined) { + params.body = normalizedBody; + } + } + if (options?.path) { + params.path = options.path; + } + if (options?.query !== undefined) { + const normalizedQuery = serializeQueryKeyValue(options.query); + if (normalizedQuery !== undefined) { + params.query = normalizedQuery; + } + } + return [params]; +}; + +export const getBotsQueryKey = (options?: Options) => createQueryKey('getBots', options); + +/** + * List bots + * + * List bots accessible to current user (admin can specify owner_id) + */ +export const getBotsQuery = defineQueryOptions((options?: Options) => ({ + key: getBotsQueryKey(options), + query: async (context) => { + const { data } = await getBots({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create bot user + * + * Create a bot user owned by current user (or admin-specified owner) + */ +export const postBotsMutation = (options?: Partial>): UseMutationOptions, PostBotsError> => ({ + mutation: async (vars) => { + const { data } = await postBots({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Chat with AI + * + * Send a chat message and get a response. The system will automatically select an appropriate chat model from the database. + */ +export const postBotsByBotIdChatMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdChatError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdChat({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Stream chat with AI + * + * Send a chat message and get a streaming response. The system will automatically select an appropriate chat model from the database. + */ +export const postBotsByBotIdChatStreamMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdChatStreamError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdChatStream({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete MCP container for bot + */ +export const deleteBotsByBotIdContainerMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdContainerError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdContainer({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainer', options); + +/** + * Get container info for bot + */ +export const getBotsByBotIdContainerQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainer({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create and start MCP container for bot + */ +export const postBotsByBotIdContainerMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainer({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete a file or directory + */ +export const deleteBotsByBotIdContainerFsMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdContainerFsError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdContainerFs({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerFsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerFs', options); + +/** + * List files for a bot + * + * List entries under a relative path + */ +export const getBotsByBotIdContainerFsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerFsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerFs({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * MCP filesystem tools (JSON-RPC) + * + * Forwards MCP JSON-RPC requests to the MCP server inside the container. + * Required: + * - container task is running + * - container has data mount (default /data) bound to /users/ + * - container image contains the "mcp" binary + * Auth: Bearer JWT is used to determine user_id (sub or user_id). + * Paths must be relative (no leading slash) and must not contain "..". + * + * Example: tools/list + * {"jsonrpc":"2.0","id":1,"method":"tools/list"} + * + * Example: tools/call (fs.read) + * {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"fs.read","arguments":{"path":"notes.txt"}}} + */ +export const postBotsByBotIdContainerFsMcpMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerFsMcpError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerFsMcp({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Create a directory + */ +export const postBotsByBotIdContainerFsDirMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerFsDirError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerFsDir({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerFsFileQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerFsFile', options); + +/** + * Read file content + */ +export const getBotsByBotIdContainerFsFileQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerFsFileQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerFsFile({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create or overwrite a file + */ +export const postBotsByBotIdContainerFsFileMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerFsFileError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerFsFile({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerFsStatQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerFsStat', options); + +/** + * Get file or directory metadata + */ +export const getBotsByBotIdContainerFsStatQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerFsStatQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerFsStat({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Upload a file + */ +export const postBotsByBotIdContainerFsUploadMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerFsUploadError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerFsUpload({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerFsUsageQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerFsUsage', options); + +/** + * Get usage under a path + */ +export const getBotsByBotIdContainerFsUsageQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerFsUsageQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerFsUsage({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Delete skills from data directory + */ +export const deleteBotsByBotIdContainerSkillsMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdContainerSkillsError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdContainerSkills({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerSkillsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerSkills', options); + +/** + * List skills from data directory + */ +export const getBotsByBotIdContainerSkillsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerSkillsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerSkills({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Upload skills into data directory + */ +export const postBotsByBotIdContainerSkillsMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerSkillsError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerSkills({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdContainerSnapshotsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdContainerSnapshots', options); + +/** + * List snapshots + */ +export const getBotsByBotIdContainerSnapshotsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdContainerSnapshotsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdContainerSnapshots({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create container snapshot for bot + */ +export const postBotsByBotIdContainerSnapshotsMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerSnapshotsError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerSnapshots({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Start container task for bot + */ +export const postBotsByBotIdContainerStartMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerStartError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerStart({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Stop container task for bot + */ +export const postBotsByBotIdContainerStopMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdContainerStopError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdContainerStop({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete all history records + * + * Delete all history records for current user + */ +export const deleteBotsByBotIdHistoryMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdHistoryError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdHistory({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdHistoryQueryKey = (options: Options) => createQueryKey('getBotsByBotIdHistory', options); + +/** + * List history records + * + * List history records for current user + */ +export const getBotsByBotIdHistoryQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdHistoryQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdHistory({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create history record + * + * Create a history record for current user + */ +export const postBotsByBotIdHistoryMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdHistoryError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdHistory({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete history record + * + * Delete a history record by ID (must belong to current user) + */ +export const deleteBotsByBotIdHistoryByIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdHistoryByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdHistoryById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdHistoryByIdQueryKey = (options: Options) => createQueryKey('getBotsByBotIdHistoryById', options); + +/** + * Get history record + * + * Get a history record by ID (must belong to current user) + */ +export const getBotsByBotIdHistoryByIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdHistoryByIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdHistoryById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +export const getBotsByBotIdMcpQueryKey = (options: Options) => createQueryKey('getBotsByBotIdMcp', options); + +/** + * List MCP connections + * + * List MCP connections for a bot + */ +export const getBotsByBotIdMcpQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdMcpQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdMcp({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create MCP connection + * + * Create a MCP connection for a bot + */ +export const postBotsByBotIdMcpMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMcpError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMcp({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Create MCP stdio proxy + * + * Start a stdio MCP process in the bot container and expose it as MCP HTTP endpoint. + */ +export const postBotsByBotIdMcpStdioMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMcpStdioError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMcpStdio({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * MCP stdio proxy (JSON-RPC) + * + * Proxies MCP JSON-RPC requests to a stdio MCP process in the container. + */ +export const postBotsByBotIdMcpStdioBySessionIdMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMcpStdioBySessionIdError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMcpStdioBySessionId({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete MCP connection + * + * Delete a MCP connection by ID + */ +export const deleteBotsByBotIdMcpByIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdMcpByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdMcpById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdMcpByIdQueryKey = (options: Options) => createQueryKey('getBotsByBotIdMcpById', options); + +/** + * Get MCP connection + * + * Get a MCP connection by ID + */ +export const getBotsByBotIdMcpByIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdMcpByIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdMcpById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update MCP connection + * + * Update a MCP connection by ID + */ +export const putBotsByBotIdMcpByIdMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdMcpByIdError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdMcpById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Add memory + * + * Add memory for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryAddMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMemoryAddError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMemoryAdd({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Embed and upsert memory + * + * Embed text or multimodal input and upsert into memory store. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryEmbedMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMemoryEmbedError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMemoryEmbed({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete memories + * + * Delete all memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const deleteBotsByBotIdMemoryMemoriesMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdMemoryMemoriesError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdMemoryMemories({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdMemoryMemoriesQueryKey = (options: Options) => createQueryKey('getBotsByBotIdMemoryMemories', options); + +/** + * List memories + * + * List memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const getBotsByBotIdMemoryMemoriesQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdMemoryMemoriesQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdMemoryMemories({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Delete memory + * + * Delete a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const deleteBotsByBotIdMemoryMemoriesByMemoryIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdMemoryMemoriesByMemoryIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdMemoryMemoriesByMemoryId({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdMemoryMemoriesByMemoryIdQueryKey = (options: Options) => createQueryKey('getBotsByBotIdMemoryMemoriesByMemoryId', options); + +/** + * Get memory + * + * Get a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const getBotsByBotIdMemoryMemoriesByMemoryIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdMemoryMemoriesByMemoryIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdMemoryMemoriesByMemoryId({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Search memories + * + * Search memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemorySearchMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMemorySearchError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMemorySearch({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Update memory + * + * Update a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryUpdateMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdMemoryUpdateError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdMemoryUpdate({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdScheduleQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSchedule', options); + +/** + * List schedules + * + * List schedules for current user + */ +export const getBotsByBotIdScheduleQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdScheduleQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSchedule({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create schedule + * + * Create a schedule for current user + */ +export const postBotsByBotIdScheduleMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdScheduleError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdSchedule({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete schedule + * + * Delete a schedule by ID + */ +export const deleteBotsByBotIdScheduleByIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdScheduleByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdScheduleById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdScheduleByIdQueryKey = (options: Options) => createQueryKey('getBotsByBotIdScheduleById', options); + +/** + * Get schedule + * + * Get a schedule by ID + */ +export const getBotsByBotIdScheduleByIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdScheduleByIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdScheduleById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update schedule + * + * Update a schedule by ID + */ +export const putBotsByBotIdScheduleByIdMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdScheduleByIdError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdScheduleById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete user settings + * + * Remove agent settings for current user + */ +export const deleteBotsByBotIdSettingsMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdSettingsError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdSettings({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdSettingsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSettings', options); + +/** + * Get user settings + * + * Get agent settings for current user + */ +export const getBotsByBotIdSettingsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdSettingsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSettings({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update user settings + * + * Update or create agent settings for current user + */ +export const postBotsByBotIdSettingsMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdSettingsError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdSettings({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Update user settings + * + * Update or create agent settings for current user + */ +export const putBotsByBotIdSettingsMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdSettingsError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdSettings({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdSubagentsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSubagents', options); + +/** + * List subagents + * + * List subagents for current user + */ +export const getBotsByBotIdSubagentsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdSubagentsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSubagents({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create subagent + * + * Create a subagent for current user + */ +export const postBotsByBotIdSubagentsMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdSubagentsError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdSubagents({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete subagent + * + * Delete a subagent by ID + */ +export const deleteBotsByBotIdSubagentsByIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByBotIdSubagentsByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByBotIdSubagentsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdSubagentsByIdQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSubagentsById', options); + +/** + * Get subagent + * + * Get a subagent by ID + */ +export const getBotsByBotIdSubagentsByIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdSubagentsByIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSubagentsById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update subagent + * + * Update a subagent by ID + */ +export const putBotsByBotIdSubagentsByIdMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdSubagentsByIdError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdSubagentsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdSubagentsByIdContextQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSubagentsByIdContext', options); + +/** + * Get subagent context + * + * Get a subagent's message context + */ +export const getBotsByBotIdSubagentsByIdContextQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdSubagentsByIdContextQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSubagentsByIdContext({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update subagent context + * + * Update a subagent's message context + */ +export const putBotsByBotIdSubagentsByIdContextMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdSubagentsByIdContextError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdSubagentsByIdContext({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByBotIdSubagentsByIdSkillsQueryKey = (options: Options) => createQueryKey('getBotsByBotIdSubagentsByIdSkills', options); + +/** + * Get subagent skills + * + * Get a subagent's skills + */ +export const getBotsByBotIdSubagentsByIdSkillsQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByBotIdSubagentsByIdSkillsQueryKey(options), + query: async (context) => { + const { data } = await getBotsByBotIdSubagentsByIdSkills({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Add subagent skills + * + * Add skills to a subagent + */ +export const postBotsByBotIdSubagentsByIdSkillsMutation = (options?: Partial>): UseMutationOptions, PostBotsByBotIdSubagentsByIdSkillsError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByBotIdSubagentsByIdSkills({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Update subagent skills + * + * Replace a subagent's skills + */ +export const putBotsByBotIdSubagentsByIdSkillsMutation = (options?: Partial>): UseMutationOptions, PutBotsByBotIdSubagentsByIdSkillsError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByBotIdSubagentsByIdSkills({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete bot + * + * Delete a bot user (owner/admin only) + */ +export const deleteBotsByIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByIdQueryKey = (options: Options) => createQueryKey('getBotsById', options); + +/** + * Get bot details + * + * Get a bot by ID (owner/admin only) + */ +export const getBotsByIdQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByIdQueryKey(options), + query: async (context) => { + const { data } = await getBotsById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update bot details + * + * Update bot profile (owner/admin only) + */ +export const putBotsByIdMutation = (options?: Partial>): UseMutationOptions, PutBotsByIdError> => ({ + mutation: async (vars) => { + const { data } = await putBotsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByIdChannelByPlatformQueryKey = (options: Options) => createQueryKey('getBotsByIdChannelByPlatform', options); + +/** + * Get bot channel config + * + * Get bot channel configuration + */ +export const getBotsByIdChannelByPlatformQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByIdChannelByPlatformQueryKey(options), + query: async (context) => { + const { data } = await getBotsByIdChannelByPlatform({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update bot channel config + * + * Update bot channel configuration + */ +export const putBotsByIdChannelByPlatformMutation = (options?: Partial>): UseMutationOptions, PutBotsByIdChannelByPlatformError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByIdChannelByPlatform({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Send message via bot channel + * + * Send a message using bot channel configuration + */ +export const postBotsByIdChannelByPlatformSendMutation = (options?: Partial>): UseMutationOptions, PostBotsByIdChannelByPlatformSendError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByIdChannelByPlatformSend({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Send message via bot channel session token + * + * Send a message using a session-scoped token (reply only) + */ +export const postBotsByIdChannelByPlatformSendSessionMutation = (options?: Partial>): UseMutationOptions, PostBotsByIdChannelByPlatformSendSessionError> => ({ + mutation: async (vars) => { + const { data } = await postBotsByIdChannelByPlatformSendSession({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getBotsByIdMembersQueryKey = (options: Options) => createQueryKey('getBotsByIdMembers', options); + +/** + * List bot members + * + * List members for a bot + */ +export const getBotsByIdMembersQuery = defineQueryOptions((options: Options) => ({ + key: getBotsByIdMembersQueryKey(options), + query: async (context) => { + const { data } = await getBotsByIdMembers({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Upsert bot member + * + * Add or update bot member role + */ +export const putBotsByIdMembersMutation = (options?: Partial>): UseMutationOptions, PutBotsByIdMembersError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByIdMembers({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete bot member + * + * Remove a member from a bot + */ +export const deleteBotsByIdMembersByUserIdMutation = (options?: Partial>): UseMutationOptions, DeleteBotsByIdMembersByUserIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteBotsByIdMembersByUserId({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Transfer bot owner (admin only) + * + * Transfer bot ownership to another human user + */ +export const putBotsByIdOwnerMutation = (options?: Partial>): UseMutationOptions, PutBotsByIdOwnerError> => ({ + mutation: async (vars) => { + const { data } = await putBotsByIdOwner({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getChannelsQueryKey = (options?: Options) => createQueryKey('getChannels', options); + +/** + * List channel capabilities and schemas + * + * List channel meta information including capabilities and schemas + */ +export const getChannelsQuery = defineQueryOptions((options?: Options) => ({ + key: getChannelsQueryKey(options), + query: async (context) => { + const { data } = await getChannels({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +export const getChannelsByPlatformQueryKey = (options: Options) => createQueryKey('getChannelsByPlatform', options); + +/** + * Get channel capabilities and schemas + * + * Get channel meta information including capabilities and schemas + */ +export const getChannelsByPlatformQuery = defineQueryOptions((options: Options) => ({ + key: getChannelsByPlatformQueryKey(options), + query: async (context) => { + const { data } = await getChannelsByPlatform({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create embeddings + * + * Create text or multimodal embeddings + */ +export const postEmbeddingsMutation = (options?: Partial>): UseMutationOptions, PostEmbeddingsError> => ({ + mutation: async (vars) => { + const { data } = await postEmbeddings({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getModelsQueryKey = (options?: Options) => createQueryKey('getModels', options); + +/** + * List all models + * + * Get a list of all configured models, optionally filtered by type or client type + */ +export const getModelsQuery = defineQueryOptions((options?: Options) => ({ + key: getModelsQueryKey(options), + query: async (context) => { + const { data } = await getModels({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create a new model + * + * Create a new model configuration + */ +export const postModelsMutation = (options?: Partial>): UseMutationOptions, PostModelsError> => ({ + mutation: async (vars) => { + const { data } = await postModels({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getModelsCountQueryKey = (options?: Options) => createQueryKey('getModelsCount', options); + +/** + * Get model count + * + * Get the total count of models, optionally filtered by type + */ +export const getModelsCountQuery = defineQueryOptions((options?: Options) => ({ + key: getModelsCountQueryKey(options), + query: async (context) => { + const { data } = await getModelsCount({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Enable model for chat/memory/embedding + * + * Update the current user's settings to use the selected model + */ +export const postModelsEnableMutation = (options?: Partial>): UseMutationOptions, PostModelsEnableError> => ({ + mutation: async (vars) => { + const { data } = await postModelsEnable({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete model by model ID + * + * Delete a model configuration by its model_id field (e.g., gpt-4) + */ +export const deleteModelsModelByModelIdMutation = (options?: Partial>): UseMutationOptions, DeleteModelsModelByModelIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteModelsModelByModelId({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getModelsModelByModelIdQueryKey = (options: Options) => createQueryKey('getModelsModelByModelId', options); + +/** + * Get model by model ID + * + * Get a model configuration by its model_id field (e.g., gpt-4) + */ +export const getModelsModelByModelIdQuery = defineQueryOptions((options: Options) => ({ + key: getModelsModelByModelIdQueryKey(options), + query: async (context) => { + const { data } = await getModelsModelByModelId({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update model by model ID + * + * Update a model configuration by its model_id field (e.g., gpt-4) + */ +export const putModelsModelByModelIdMutation = (options?: Partial>): UseMutationOptions, PutModelsModelByModelIdError> => ({ + mutation: async (vars) => { + const { data } = await putModelsModelByModelId({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Delete model by internal ID + * + * Delete a model configuration by its internal UUID + */ +export const deleteModelsByIdMutation = (options?: Partial>): UseMutationOptions, DeleteModelsByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteModelsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getModelsByIdQueryKey = (options: Options) => createQueryKey('getModelsById', options); + +/** + * Get model by internal ID + * + * Get a model configuration by its internal UUID + */ +export const getModelsByIdQuery = defineQueryOptions((options: Options) => ({ + key: getModelsByIdQueryKey(options), + query: async (context) => { + const { data } = await getModelsById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update model by internal ID + * + * Update a model configuration by its internal UUID + */ +export const putModelsByIdMutation = (options?: Partial>): UseMutationOptions, PutModelsByIdError> => ({ + mutation: async (vars) => { + const { data } = await putModelsById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getProvidersQueryKey = (options?: Options) => createQueryKey('getProviders', options); + +/** + * List all LLM providers + * + * Get a list of all configured LLM providers, optionally filtered by client type + */ +export const getProvidersQuery = defineQueryOptions((options?: Options) => ({ + key: getProvidersQueryKey(options), + query: async (context) => { + const { data } = await getProviders({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create a new LLM provider + * + * Create a new LLM provider configuration + */ +export const postProvidersMutation = (options?: Partial>): UseMutationOptions, PostProvidersError> => ({ + mutation: async (vars) => { + const { data } = await postProviders({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getProvidersCountQueryKey = (options?: Options) => createQueryKey('getProvidersCount', options); + +/** + * Count providers + * + * Get the total count of providers, optionally filtered by client type + */ +export const getProvidersCountQuery = defineQueryOptions((options?: Options) => ({ + key: getProvidersCountQueryKey(options), + query: async (context) => { + const { data } = await getProvidersCount({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +export const getProvidersNameByNameQueryKey = (options: Options) => createQueryKey('getProvidersNameByName', options); + +/** + * Get provider by name + * + * Get a provider configuration by its name + */ +export const getProvidersNameByNameQuery = defineQueryOptions((options: Options) => ({ + key: getProvidersNameByNameQueryKey(options), + query: async (context) => { + const { data } = await getProvidersNameByName({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Delete provider + * + * Delete a provider configuration + */ +export const deleteProvidersByIdMutation = (options?: Partial>): UseMutationOptions, DeleteProvidersByIdError> => ({ + mutation: async (vars) => { + const { data } = await deleteProvidersById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getProvidersByIdQueryKey = (options: Options) => createQueryKey('getProvidersById', options); + +/** + * Get provider by ID + * + * Get a provider configuration by its ID + */ +export const getProvidersByIdQuery = defineQueryOptions((options: Options) => ({ + key: getProvidersByIdQueryKey(options), + query: async (context) => { + const { data } = await getProvidersById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update provider + * + * Update an existing provider configuration + */ +export const putProvidersByIdMutation = (options?: Partial>): UseMutationOptions, PutProvidersByIdError> => ({ + mutation: async (vars) => { + const { data } = await putProvidersById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getProvidersByIdModelsQueryKey = (options: Options) => createQueryKey('getProvidersByIdModels', options); + +/** + * List provider models + * + * Get models for a provider by id, optionally filtered by type + */ +export const getProvidersByIdModelsQuery = defineQueryOptions((options: Options) => ({ + key: getProvidersByIdModelsQueryKey(options), + query: async (context) => { + const { data } = await getProvidersByIdModels({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +export const getUsersQueryKey = (options?: Options) => createQueryKey('getUsers', options); + +/** + * List users (admin only) + * + * List users + */ +export const getUsersQuery = defineQueryOptions((options?: Options) => ({ + key: getUsersQueryKey(options), + query: async (context) => { + const { data } = await getUsers({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Create human user (admin only) + * + * Create a new human user account + */ +export const postUsersMutation = (options?: Partial>): UseMutationOptions, PostUsersError> => ({ + mutation: async (vars) => { + const { data } = await postUsers({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getUsersMeQueryKey = (options?: Options) => createQueryKey('getUsersMe', options); + +/** + * Get current user + * + * Get current user profile + */ +export const getUsersMeQuery = defineQueryOptions((options?: Options) => ({ + key: getUsersMeQueryKey(options), + query: async (context) => { + const { data } = await getUsersMe({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update current user profile + * + * Update current user display name or avatar + */ +export const putUsersMeMutation = (options?: Partial>): UseMutationOptions, PutUsersMeError> => ({ + mutation: async (vars) => { + const { data } = await putUsersMe({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getUsersMeChannelsByPlatformQueryKey = (options: Options) => createQueryKey('getUsersMeChannelsByPlatform', options); + +/** + * Get channel user config + * + * Get channel binding configuration for current user + */ +export const getUsersMeChannelsByPlatformQuery = defineQueryOptions((options: Options) => ({ + key: getUsersMeChannelsByPlatformQueryKey(options), + query: async (context) => { + const { data } = await getUsersMeChannelsByPlatform({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update channel user config + * + * Update channel binding configuration for current user + */ +export const putUsersMeChannelsByPlatformMutation = (options?: Partial>): UseMutationOptions, PutUsersMeChannelsByPlatformError> => ({ + mutation: async (vars) => { + const { data } = await putUsersMeChannelsByPlatform({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Update current user password + * + * Update current user password with current password check + */ +export const putUsersMePasswordMutation = (options?: Partial>): UseMutationOptions, PutUsersMePasswordError> => ({ + mutation: async (vars) => { + const { data } = await putUsersMePassword({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +export const getUsersByIdQueryKey = (options: Options) => createQueryKey('getUsersById', options); + +/** + * Get user by ID + * + * Get user details (self or admin only) + */ +export const getUsersByIdQuery = defineQueryOptions((options: Options) => ({ + key: getUsersByIdQueryKey(options), + query: async (context) => { + const { data } = await getUsersById({ + ...options, + ...context, + throwOnError: true + }); + return data; + } +})); + +/** + * Update user (admin only) + * + * Update user profile and status + */ +export const putUsersByIdMutation = (options?: Partial>): UseMutationOptions, PutUsersByIdError> => ({ + mutation: async (vars) => { + const { data } = await putUsersById({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); + +/** + * Reset user password (admin only) + * + * Reset a user password + */ +export const putUsersByIdPasswordMutation = (options?: Partial>): UseMutationOptions, PutUsersByIdPasswordError> => ({ + mutation: async (vars) => { + const { data } = await putUsersByIdPassword({ + ...options, + ...vars, + throwOnError: true + }); + return data; + } +}); diff --git a/packages/sdk/src/client.gen.ts b/packages/sdk/src/client.gen.ts new file mode 100644 index 00000000..cab3c701 --- /dev/null +++ b/packages/sdk/src/client.gen.ts @@ -0,0 +1,16 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { type ClientOptions, type Config, createClient, createConfig } from './client'; +import type { ClientOptions as ClientOptions2 } from './types.gen'; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = (override?: Config) => Config & T>; + +export const client = createClient(createConfig()); diff --git a/packages/sdk/src/client/client.gen.ts b/packages/sdk/src/client/client.gen.ts new file mode 100644 index 00000000..d2e55a14 --- /dev/null +++ b/packages/sdk/src/client/client.gen.ts @@ -0,0 +1,288 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import { getValidRequestBody } from '../core/utils.gen'; +import type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body !== undefined && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body); + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.body === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: getValidRequestBody(opts), + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response: Response; + + try { + response = await _fetch(request); + } catch (error) { + // Handle fetch exceptions (AbortError, network errors, etc.) + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn(error, undefined as any, request, opts)) as unknown; + } + } + + finalError = finalError || ({} as unknown); + + if (opts.throwOnError) { + throw finalError; + } + + // Return error response + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + request, + response: undefined as any, + }; + } + + for (const fn of interceptors.response.fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + if (response.status === 204 || response.headers.get('Content-Length') === '0') { + let emptyData: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'text': + emptyData = await response[parseAs](); + break; + case 'formData': + emptyData = new FormData(); + break; + case 'stream': + emptyData = response.body; + break; + case 'json': + default: + emptyData = {}; + break; + } + return opts.responseStyle === 'data' + ? emptyData + : { + data: emptyData, + ...result, + }; + } + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'text': + data = await response[parseAs](); + break; + case 'json': { + // Some servers return 200 with no Content-Length and empty body. + // response.json() would throw; read as text and parse if non-empty. + const text = await response.text(); + data = text ? JSON.parse(text) : {}; + break; + } + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error.fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + onRequest: async (url, init) => { + let request = new Request(url, init); + for (const fn of interceptors.request.fns) { + if (fn) { + request = await fn(request, opts); + } + } + return request; + }, + serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/packages/sdk/src/client/index.ts b/packages/sdk/src/client/index.ts new file mode 100644 index 00000000..b295edec --- /dev/null +++ b/packages/sdk/src/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { serializeQueryKeyValue } from '../core/queryKeySerializer.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/packages/sdk/src/client/types.gen.ts b/packages/sdk/src/client/types.gen.ts new file mode 100644 index 00000000..cb6d0d54 --- /dev/null +++ b/packages/sdk/src/client/types.gen.ts @@ -0,0 +1,213 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> + extends + Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record ? TData[keyof TData] : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? (TData extends Record ? TData[keyof TData] : TData) | undefined + : ( + | { + data: TData extends Record ? TData[keyof TData] : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record ? TError[keyof TError] : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick>, 'method'>, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: TData & Options, +) => string; + +export type Client = CoreClient & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + ([TData] extends [never] ? unknown : Omit); diff --git a/packages/sdk/src/client/utils.gen.ts b/packages/sdk/src/client/utils.gen.ts new file mode 100644 index 00000000..b4bd2435 --- /dev/null +++ b/packages/sdk/src/client/utils.gen.ts @@ -0,0 +1,316 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + parameters = {}, + ...args +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + const options = parameters[name] || args; + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'form', + value, + ...options.array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved: options.allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...options.object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved: options.allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = (contentType: string | null): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type)) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +const headersEntries = (headers: Headers): Array<[string, string]> => { + const entries: Array<[string, string]> = []; + headers.forEach((value, key) => { + entries.push([key, value]); + }); + return entries; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header) { + continue; + } + + const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = (request: Req, options: Options) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + fns: Array = []; + + clear(): void { + this.fns = []; + } + + eject(id: number | Interceptor): void { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = null; + } + } + + exists(id: number | Interceptor): boolean { + const index = this.getInterceptorIndex(id); + return Boolean(this.fns[index]); + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this.fns[id] ? id : -1; + } + return this.fns.indexOf(id); + } + + update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false { + const index = this.getInterceptorIndex(id); + if (this.fns[index]) { + this.fns[index] = fn; + return id; + } + return false; + } + + use(fn: Interceptor): number { + this.fns.push(fn); + return this.fns.length - 1; + } +} + +export interface Middleware { + error: Interceptors>; + request: Interceptors>; + response: Interceptors>; +} + +export const createInterceptors = (): Middleware< + Req, + Res, + Err, + Options +> => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/packages/sdk/src/core/auth.gen.ts b/packages/sdk/src/core/auth.gen.ts new file mode 100644 index 00000000..3ebf9947 --- /dev/null +++ b/packages/sdk/src/core/auth.gen.ts @@ -0,0 +1,41 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/packages/sdk/src/core/bodySerializer.gen.ts b/packages/sdk/src/core/bodySerializer.gen.ts new file mode 100644 index 00000000..8ad92c9f --- /dev/null +++ b/packages/sdk/src/core/bodySerializer.gen.ts @@ -0,0 +1,84 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { ArrayStyle, ObjectStyle, SerializerOptions } from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: any) => any; + +type QuerySerializerOptionsObject = { + allowReserved?: boolean; + array?: Partial>; + object?: Partial>; +}; + +export type QuerySerializerOptions = QuerySerializerOptionsObject & { + /** + * Per-parameter serialization overrides. When provided, these settings + * override the global array/object settings for specific parameter names. + */ + parameters?: Record; +}; + +const serializeFormDataPair = (data: FormData, key: string, value: unknown): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = (data: URLSearchParams, key: string, value: unknown): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => (typeof value === 'bigint' ? value.toString() : value)), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: | Array>>(body: T): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/packages/sdk/src/core/params.gen.ts b/packages/sdk/src/core/params.gen.ts new file mode 100644 index 00000000..6099cab1 --- /dev/null +++ b/packages/sdk/src/core/params.gen.ts @@ -0,0 +1,169 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + } + | { + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If `in` is omitted, `map` aliases `key` to the transport layer. + */ + map: Slot; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + | { + in: Slot; + map?: string; + } + | { + in?: never; + map: Slot; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if ('key' in config) { + map.set(config.key, { + map: config.map, + }); + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = (args: ReadonlyArray, fields: FieldsConfig) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + if (field.in) { + (params[field.in] as Record)[name] = arg; + } + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + if (field.in) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + params[field.map] = value; + } + } else { + const extra = extraPrefixes.find(([prefix]) => key.startsWith(prefix)); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[key.slice(prefix.length)] = value; + } else if ('allowExtra' in config && config.allowExtra) { + for (const [slot, allowed] of Object.entries(config.allowExtra)) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/packages/sdk/src/core/pathSerializer.gen.ts b/packages/sdk/src/core/pathSerializer.gen.ts new file mode 100644 index 00000000..994b2848 --- /dev/null +++ b/packages/sdk/src/core/pathSerializer.gen.ts @@ -0,0 +1,171 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions extends SerializePrimitiveOptions, SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [...values, key, allowReserved ? (v as string) : encodeURIComponent(v as string)]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' ? separator + joinedValues : joinedValues; +}; diff --git a/packages/sdk/src/core/queryKeySerializer.gen.ts b/packages/sdk/src/core/queryKeySerializer.gen.ts new file mode 100644 index 00000000..5000df60 --- /dev/null +++ b/packages/sdk/src/core/queryKeySerializer.gen.ts @@ -0,0 +1,117 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * JSON-friendly union that mirrors what Pinia Colada can hash. + */ +export type JsonValue = + | null + | string + | number + | boolean + | JsonValue[] + | { [key: string]: JsonValue }; + +/** + * Replacer that converts non-JSON values (bigint, Date, etc.) to safe substitutes. + */ +export const queryKeyJsonReplacer = (_key: string, value: unknown) => { + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + if (typeof value === 'bigint') { + return value.toString(); + } + if (value instanceof Date) { + return value.toISOString(); + } + return value; +}; + +/** + * Safely stringifies a value and parses it back into a JsonValue. + */ +export const stringifyToJsonValue = (input: unknown): JsonValue | undefined => { + try { + const json = JSON.stringify(input, queryKeyJsonReplacer); + if (json === undefined) { + return undefined; + } + return JSON.parse(json) as JsonValue; + } catch { + return undefined; + } +}; + +/** + * Detects plain objects (including objects with a null prototype). + */ +const isPlainObject = (value: unknown): value is Record => { + if (value === null || typeof value !== 'object') { + return false; + } + const prototype = Object.getPrototypeOf(value as object); + return prototype === Object.prototype || prototype === null; +}; + +/** + * Turns URLSearchParams into a sorted JSON object for deterministic keys. + */ +const serializeSearchParams = (params: URLSearchParams): JsonValue => { + const entries = Array.from(params.entries()).sort(([a], [b]) => a.localeCompare(b)); + const result: Record = {}; + + for (const [key, value] of entries) { + const existing = result[key]; + if (existing === undefined) { + result[key] = value; + continue; + } + + if (Array.isArray(existing)) { + (existing as string[]).push(value); + } else { + result[key] = [existing, value]; + } + } + + return result; +}; + +/** + * Normalizes any accepted value into a JSON-friendly shape for query keys. + */ +export const serializeQueryKeyValue = (value: unknown): JsonValue | undefined => { + if (value === null) { + return null; + } + + if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') { + return value; + } + + if (value === undefined || typeof value === 'function' || typeof value === 'symbol') { + return undefined; + } + + if (typeof value === 'bigint') { + return value.toString(); + } + + if (value instanceof Date) { + return value.toISOString(); + } + + if (Array.isArray(value)) { + return stringifyToJsonValue(value); + } + + if (typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams) { + return serializeSearchParams(value); + } + + if (isPlainObject(value)) { + return stringifyToJsonValue(value); + } + + return undefined; +}; diff --git a/packages/sdk/src/core/serverSentEvents.gen.ts b/packages/sdk/src/core/serverSentEvents.gen.ts new file mode 100644 index 00000000..6aa6cf02 --- /dev/null +++ b/packages/sdk/src/core/serverSentEvents.gen.ts @@ -0,0 +1,243 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit & + Pick & { + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: typeof fetch; + /** + * Implementing clients can call request interceptors inside this hook. + */ + onRequest?: (url: string, init: RequestInit) => Promise; + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + serializedBody?: RequestInit['body']; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onRequest, + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = sseSleepFn ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const requestInit: RequestInit = { + redirect: 'follow', + ...options, + body: options.serializedBody, + headers, + signal, + }; + let request = new Request(url, requestInit); + if (onRequest) { + request = await onRequest(url, requestInit); + } + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = options.fetch ?? globalThis.fetch; + const response = await _fetch(request); + + if (!response.ok) throw new Error(`SSE failed: ${response.status} ${response.statusText}`); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + // Normalize line endings: CRLF -> LF, then CR -> LF + buffer = buffer.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt(line.replace(/^retry:\s*/, ''), 10); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if (sseMaxRetryAttempts !== undefined && attempt >= sseMaxRetryAttempts) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min(retryDelay * 2 ** (attempt - 1), sseMaxRetryDelay ?? 30000); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/packages/sdk/src/core/types.gen.ts b/packages/sdk/src/core/types.gen.ts new file mode 100644 index 00000000..97463257 --- /dev/null +++ b/packages/sdk/src/core/types.gen.ts @@ -0,0 +1,104 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { BodySerializer, QuerySerializer, QuerySerializerOptions } from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] ? { sse?: never } : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + string | number | boolean | (string | number | boolean)[] | null | undefined | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true ? never : K]: T[K]; +}; diff --git a/packages/sdk/src/core/utils.gen.ts b/packages/sdk/src/core/utils.gen.ts new file mode 100644 index 00000000..e7ddbe35 --- /dev/null +++ b/packages/sdk/src/core/utils.gen.ts @@ -0,0 +1,140 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { BodySerializer, QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace(match, serializeArrayParam({ explode, name, style, value })); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; + +export function getValidRequestBody(options: { + body?: unknown; + bodySerializer?: BodySerializer | null; + serializedBody?: unknown; +}) { + const hasBody = options.body !== undefined; + const isSerializedBody = hasBody && options.bodySerializer; + + if (isSerializedBody) { + if ('serializedBody' in options) { + const hasSerializedBody = + options.serializedBody !== undefined && options.serializedBody !== ''; + + return hasSerializedBody ? options.serializedBody : null; + } + + // not all clients implement a serializedBody property (i.e. client-axios) + return options.body !== '' ? options.body : null; + } + + // plain/text body + if (hasBody) { + return options.body; + } + + // no body was provided + return undefined; +} diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts new file mode 100644 index 00000000..904fad11 --- /dev/null +++ b/packages/sdk/src/index.ts @@ -0,0 +1,4 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export { deleteBotsByBotIdContainer, deleteBotsByBotIdContainerFs, deleteBotsByBotIdContainerSkills, deleteBotsByBotIdHistory, deleteBotsByBotIdHistoryById, deleteBotsByBotIdMcpById, deleteBotsByBotIdMemoryMemories, deleteBotsByBotIdMemoryMemoriesByMemoryId, deleteBotsByBotIdScheduleById, deleteBotsByBotIdSettings, deleteBotsByBotIdSubagentsById, deleteBotsById, deleteBotsByIdMembersByUserId, deleteModelsById, deleteModelsModelByModelId, deleteProvidersById, getBots, getBotsByBotIdContainer, getBotsByBotIdContainerFs, getBotsByBotIdContainerFsFile, getBotsByBotIdContainerFsStat, getBotsByBotIdContainerFsUsage, getBotsByBotIdContainerSkills, getBotsByBotIdContainerSnapshots, getBotsByBotIdHistory, getBotsByBotIdHistoryById, getBotsByBotIdMcp, getBotsByBotIdMcpById, getBotsByBotIdMemoryMemories, getBotsByBotIdMemoryMemoriesByMemoryId, getBotsByBotIdSchedule, getBotsByBotIdScheduleById, getBotsByBotIdSettings, getBotsByBotIdSubagents, getBotsByBotIdSubagentsById, getBotsByBotIdSubagentsByIdContext, getBotsByBotIdSubagentsByIdSkills, getBotsById, getBotsByIdChannelByPlatform, getBotsByIdMembers, getChannels, getChannelsByPlatform, getModels, getModelsById, getModelsCount, getModelsModelByModelId, getProviders, getProvidersById, getProvidersByIdModels, getProvidersCount, getProvidersNameByName, getUsers, getUsersById, getUsersMe, getUsersMeChannelsByPlatform, type Options, postAuthLogin, postBots, postBotsByBotIdChat, postBotsByBotIdChatStream, postBotsByBotIdContainer, postBotsByBotIdContainerFsDir, postBotsByBotIdContainerFsFile, postBotsByBotIdContainerFsMcp, postBotsByBotIdContainerFsUpload, postBotsByBotIdContainerSkills, postBotsByBotIdContainerSnapshots, postBotsByBotIdContainerStart, postBotsByBotIdContainerStop, postBotsByBotIdHistory, postBotsByBotIdMcp, postBotsByBotIdMcpStdio, postBotsByBotIdMcpStdioBySessionId, postBotsByBotIdMemoryAdd, postBotsByBotIdMemoryEmbed, postBotsByBotIdMemorySearch, postBotsByBotIdMemoryUpdate, postBotsByBotIdSchedule, postBotsByBotIdSettings, postBotsByBotIdSubagents, postBotsByBotIdSubagentsByIdSkills, postBotsByIdChannelByPlatformSend, postBotsByIdChannelByPlatformSendSession, postEmbeddings, postModels, postModelsEnable, postProviders, postUsers, putBotsByBotIdMcpById, putBotsByBotIdScheduleById, putBotsByBotIdSettings, putBotsByBotIdSubagentsById, putBotsByBotIdSubagentsByIdContext, putBotsByBotIdSubagentsByIdSkills, putBotsById, putBotsByIdChannelByPlatform, putBotsByIdMembers, putBotsByIdOwner, putModelsById, putModelsModelByModelId, putProvidersById, putUsersById, putUsersByIdPassword, putUsersMe, putUsersMeChannelsByPlatform, putUsersMePassword } from './sdk.gen'; +export type { BotsBot, BotsBotMember, BotsCreateBotRequest, BotsListBotsResponse, BotsListMembersResponse, BotsTransferBotRequest, BotsUpdateBotRequest, BotsUpsertMemberRequest, ChannelAction, ChannelAttachment, ChannelAttachmentType, ChannelChannelCapabilities, ChannelChannelConfig, ChannelChannelUserBinding, ChannelConfigSchema, ChannelFieldSchema, ChannelFieldType, ChannelMessage, ChannelMessageFormat, ChannelMessagePart, ChannelMessagePartType, ChannelMessageTextStyle, ChannelReplyRef, ChannelSendRequest, ChannelTargetHint, ChannelTargetSpec, ChannelThreadRef, ChannelUpsertConfigRequest, ChannelUpsertUserConfigRequest, ChatChatRequest, ChatChatResponse, ChatModelMessage, ChatToolCall, ChatToolCallFunction, ClientOptions, DeleteBotsByBotIdContainerData, DeleteBotsByBotIdContainerError, DeleteBotsByBotIdContainerErrors, DeleteBotsByBotIdContainerFsData, DeleteBotsByBotIdContainerFsError, DeleteBotsByBotIdContainerFsErrors, DeleteBotsByBotIdContainerFsResponse, DeleteBotsByBotIdContainerFsResponses, DeleteBotsByBotIdContainerResponses, DeleteBotsByBotIdContainerSkillsData, DeleteBotsByBotIdContainerSkillsError, DeleteBotsByBotIdContainerSkillsErrors, DeleteBotsByBotIdContainerSkillsResponse, DeleteBotsByBotIdContainerSkillsResponses, DeleteBotsByBotIdHistoryByIdData, DeleteBotsByBotIdHistoryByIdError, DeleteBotsByBotIdHistoryByIdErrors, DeleteBotsByBotIdHistoryByIdResponses, DeleteBotsByBotIdHistoryData, DeleteBotsByBotIdHistoryError, DeleteBotsByBotIdHistoryErrors, DeleteBotsByBotIdHistoryResponses, DeleteBotsByBotIdMcpByIdData, DeleteBotsByBotIdMcpByIdError, DeleteBotsByBotIdMcpByIdErrors, DeleteBotsByBotIdMcpByIdResponses, DeleteBotsByBotIdMemoryMemoriesByMemoryIdData, DeleteBotsByBotIdMemoryMemoriesByMemoryIdError, DeleteBotsByBotIdMemoryMemoriesByMemoryIdErrors, DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponse, DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponses, DeleteBotsByBotIdMemoryMemoriesData, DeleteBotsByBotIdMemoryMemoriesError, DeleteBotsByBotIdMemoryMemoriesErrors, DeleteBotsByBotIdMemoryMemoriesResponse, DeleteBotsByBotIdMemoryMemoriesResponses, DeleteBotsByBotIdScheduleByIdData, DeleteBotsByBotIdScheduleByIdError, DeleteBotsByBotIdScheduleByIdErrors, DeleteBotsByBotIdScheduleByIdResponses, DeleteBotsByBotIdSettingsData, DeleteBotsByBotIdSettingsError, DeleteBotsByBotIdSettingsErrors, DeleteBotsByBotIdSettingsResponses, DeleteBotsByBotIdSubagentsByIdData, DeleteBotsByBotIdSubagentsByIdError, DeleteBotsByBotIdSubagentsByIdErrors, DeleteBotsByBotIdSubagentsByIdResponses, DeleteBotsByIdData, DeleteBotsByIdError, DeleteBotsByIdErrors, DeleteBotsByIdMembersByUserIdData, DeleteBotsByIdMembersByUserIdError, DeleteBotsByIdMembersByUserIdErrors, DeleteBotsByIdMembersByUserIdResponses, DeleteBotsByIdResponses, DeleteModelsByIdData, DeleteModelsByIdError, DeleteModelsByIdErrors, DeleteModelsByIdResponses, DeleteModelsModelByModelIdData, DeleteModelsModelByModelIdError, DeleteModelsModelByModelIdErrors, DeleteModelsModelByModelIdResponses, DeleteProvidersByIdData, DeleteProvidersByIdError, DeleteProvidersByIdErrors, DeleteProvidersByIdResponses, GetBotsByBotIdContainerData, GetBotsByBotIdContainerError, GetBotsByBotIdContainerErrors, GetBotsByBotIdContainerFsData, GetBotsByBotIdContainerFsError, GetBotsByBotIdContainerFsErrors, GetBotsByBotIdContainerFsFileData, GetBotsByBotIdContainerFsFileError, GetBotsByBotIdContainerFsFileErrors, GetBotsByBotIdContainerFsFileResponse, GetBotsByBotIdContainerFsFileResponses, GetBotsByBotIdContainerFsResponse, GetBotsByBotIdContainerFsResponses, GetBotsByBotIdContainerFsStatData, GetBotsByBotIdContainerFsStatError, GetBotsByBotIdContainerFsStatErrors, GetBotsByBotIdContainerFsStatResponse, GetBotsByBotIdContainerFsStatResponses, GetBotsByBotIdContainerFsUsageData, GetBotsByBotIdContainerFsUsageError, GetBotsByBotIdContainerFsUsageErrors, GetBotsByBotIdContainerFsUsageResponse, GetBotsByBotIdContainerFsUsageResponses, GetBotsByBotIdContainerResponse, GetBotsByBotIdContainerResponses, GetBotsByBotIdContainerSkillsData, GetBotsByBotIdContainerSkillsError, GetBotsByBotIdContainerSkillsErrors, GetBotsByBotIdContainerSkillsResponse, GetBotsByBotIdContainerSkillsResponses, GetBotsByBotIdContainerSnapshotsData, GetBotsByBotIdContainerSnapshotsResponse, GetBotsByBotIdContainerSnapshotsResponses, GetBotsByBotIdHistoryByIdData, GetBotsByBotIdHistoryByIdError, GetBotsByBotIdHistoryByIdErrors, GetBotsByBotIdHistoryByIdResponse, GetBotsByBotIdHistoryByIdResponses, GetBotsByBotIdHistoryData, GetBotsByBotIdHistoryError, GetBotsByBotIdHistoryErrors, GetBotsByBotIdHistoryResponse, GetBotsByBotIdHistoryResponses, GetBotsByBotIdMcpByIdData, GetBotsByBotIdMcpByIdError, GetBotsByBotIdMcpByIdErrors, GetBotsByBotIdMcpByIdResponse, GetBotsByBotIdMcpByIdResponses, GetBotsByBotIdMcpData, GetBotsByBotIdMcpError, GetBotsByBotIdMcpErrors, GetBotsByBotIdMcpResponse, GetBotsByBotIdMcpResponses, GetBotsByBotIdMemoryMemoriesByMemoryIdData, GetBotsByBotIdMemoryMemoriesByMemoryIdError, GetBotsByBotIdMemoryMemoriesByMemoryIdErrors, GetBotsByBotIdMemoryMemoriesByMemoryIdResponse, GetBotsByBotIdMemoryMemoriesByMemoryIdResponses, GetBotsByBotIdMemoryMemoriesData, GetBotsByBotIdMemoryMemoriesError, GetBotsByBotIdMemoryMemoriesErrors, GetBotsByBotIdMemoryMemoriesResponse, GetBotsByBotIdMemoryMemoriesResponses, GetBotsByBotIdScheduleByIdData, GetBotsByBotIdScheduleByIdError, GetBotsByBotIdScheduleByIdErrors, GetBotsByBotIdScheduleByIdResponse, GetBotsByBotIdScheduleByIdResponses, GetBotsByBotIdScheduleData, GetBotsByBotIdScheduleError, GetBotsByBotIdScheduleErrors, GetBotsByBotIdScheduleResponse, GetBotsByBotIdScheduleResponses, GetBotsByBotIdSettingsData, GetBotsByBotIdSettingsError, GetBotsByBotIdSettingsErrors, GetBotsByBotIdSettingsResponse, GetBotsByBotIdSettingsResponses, GetBotsByBotIdSubagentsByIdContextData, GetBotsByBotIdSubagentsByIdContextError, GetBotsByBotIdSubagentsByIdContextErrors, GetBotsByBotIdSubagentsByIdContextResponse, GetBotsByBotIdSubagentsByIdContextResponses, GetBotsByBotIdSubagentsByIdData, GetBotsByBotIdSubagentsByIdError, GetBotsByBotIdSubagentsByIdErrors, GetBotsByBotIdSubagentsByIdResponse, GetBotsByBotIdSubagentsByIdResponses, GetBotsByBotIdSubagentsByIdSkillsData, GetBotsByBotIdSubagentsByIdSkillsError, GetBotsByBotIdSubagentsByIdSkillsErrors, GetBotsByBotIdSubagentsByIdSkillsResponse, GetBotsByBotIdSubagentsByIdSkillsResponses, GetBotsByBotIdSubagentsData, GetBotsByBotIdSubagentsError, GetBotsByBotIdSubagentsErrors, GetBotsByBotIdSubagentsResponse, GetBotsByBotIdSubagentsResponses, GetBotsByIdChannelByPlatformData, GetBotsByIdChannelByPlatformError, GetBotsByIdChannelByPlatformErrors, GetBotsByIdChannelByPlatformResponse, GetBotsByIdChannelByPlatformResponses, GetBotsByIdData, GetBotsByIdError, GetBotsByIdErrors, GetBotsByIdMembersData, GetBotsByIdMembersError, GetBotsByIdMembersErrors, GetBotsByIdMembersResponse, GetBotsByIdMembersResponses, GetBotsByIdResponse, GetBotsByIdResponses, GetBotsData, GetBotsError, GetBotsErrors, GetBotsResponse, GetBotsResponses, GetChannelsByPlatformData, GetChannelsByPlatformError, GetChannelsByPlatformErrors, GetChannelsByPlatformResponse, GetChannelsByPlatformResponses, GetChannelsData, GetChannelsError, GetChannelsErrors, GetChannelsResponse, GetChannelsResponses, GetModelsByIdData, GetModelsByIdError, GetModelsByIdErrors, GetModelsByIdResponse, GetModelsByIdResponses, GetModelsCountData, GetModelsCountError, GetModelsCountErrors, GetModelsCountResponse, GetModelsCountResponses, GetModelsData, GetModelsError, GetModelsErrors, GetModelsModelByModelIdData, GetModelsModelByModelIdError, GetModelsModelByModelIdErrors, GetModelsModelByModelIdResponse, GetModelsModelByModelIdResponses, GetModelsResponse, GetModelsResponses, GetProvidersByIdData, GetProvidersByIdError, GetProvidersByIdErrors, GetProvidersByIdModelsData, GetProvidersByIdModelsError, GetProvidersByIdModelsErrors, GetProvidersByIdModelsResponse, GetProvidersByIdModelsResponses, GetProvidersByIdResponse, GetProvidersByIdResponses, GetProvidersCountData, GetProvidersCountError, GetProvidersCountErrors, GetProvidersCountResponse, GetProvidersCountResponses, GetProvidersData, GetProvidersError, GetProvidersErrors, GetProvidersNameByNameData, GetProvidersNameByNameError, GetProvidersNameByNameErrors, GetProvidersNameByNameResponse, GetProvidersNameByNameResponses, GetProvidersResponse, GetProvidersResponses, GetUsersByIdData, GetUsersByIdError, GetUsersByIdErrors, GetUsersByIdResponse, GetUsersByIdResponses, GetUsersData, GetUsersError, GetUsersErrors, GetUsersMeChannelsByPlatformData, GetUsersMeChannelsByPlatformError, GetUsersMeChannelsByPlatformErrors, GetUsersMeChannelsByPlatformResponse, GetUsersMeChannelsByPlatformResponses, GetUsersMeData, GetUsersMeError, GetUsersMeErrors, GetUsersMeResponse, GetUsersMeResponses, GetUsersResponse, GetUsersResponses, GithubComMemohaiMemohInternalMcpConnection, HandlersChannelMeta, HandlersCreateContainerRequest, HandlersCreateContainerResponse, HandlersCreateSnapshotRequest, HandlersCreateSnapshotResponse, HandlersEmbeddingsInput, HandlersEmbeddingsRequest, HandlersEmbeddingsResponse, HandlersEmbeddingsUsage, HandlersEnableModelRequest, HandlersErrorResponse, HandlersFsDeleteResponse, HandlersFsListResponse, HandlersFsMkdirRequest, HandlersFsReadResponse, HandlersFsRestEntry, HandlersFsStatResponse, HandlersFsUsageResponse, HandlersFsWriteRequest, HandlersFsWriteResponse, HandlersGetContainerResponse, HandlersListSnapshotsResponse, HandlersLoginRequest, HandlersLoginResponse, HandlersMcpStdioRequest, HandlersMcpStdioResponse, HandlersMemoryAddPayload, HandlersMemoryDeleteAllPayload, HandlersMemoryEmbedUpsertPayload, HandlersMemorySearchPayload, HandlersSkillItem, HandlersSkillsDeleteRequest, HandlersSkillsOpResponse, HandlersSkillsResponse, HandlersSkillsUpsertRequest, HandlersSnapshotInfo, HistoryCreateRequest, HistoryListResponse, HistoryRecord, McpListResponse, McpUpsertRequest, MemoryDeleteResponse, MemoryEmbedInput, MemoryEmbedUpsertResponse, MemoryMemoryItem, MemoryMessage, MemorySearchResponse, MemoryUpdateRequest, ModelsAddRequest, ModelsAddResponse, ModelsCountResponse, ModelsGetResponse, ModelsModelType, ModelsUpdateRequest, PostAuthLoginData, PostAuthLoginError, PostAuthLoginErrors, PostAuthLoginResponse, PostAuthLoginResponses, PostBotsByBotIdChatData, PostBotsByBotIdChatError, PostBotsByBotIdChatErrors, PostBotsByBotIdChatResponse, PostBotsByBotIdChatResponses, PostBotsByBotIdChatStreamData, PostBotsByBotIdChatStreamError, PostBotsByBotIdChatStreamErrors, PostBotsByBotIdChatStreamResponse, PostBotsByBotIdChatStreamResponses, PostBotsByBotIdContainerData, PostBotsByBotIdContainerError, PostBotsByBotIdContainerErrors, PostBotsByBotIdContainerFsDirData, PostBotsByBotIdContainerFsDirError, PostBotsByBotIdContainerFsDirErrors, PostBotsByBotIdContainerFsDirResponse, PostBotsByBotIdContainerFsDirResponses, PostBotsByBotIdContainerFsFileData, PostBotsByBotIdContainerFsFileError, PostBotsByBotIdContainerFsFileErrors, PostBotsByBotIdContainerFsFileResponse, PostBotsByBotIdContainerFsFileResponses, PostBotsByBotIdContainerFsMcpData, PostBotsByBotIdContainerFsMcpError, PostBotsByBotIdContainerFsMcpErrors, PostBotsByBotIdContainerFsMcpResponse, PostBotsByBotIdContainerFsMcpResponses, PostBotsByBotIdContainerFsUploadData, PostBotsByBotIdContainerFsUploadError, PostBotsByBotIdContainerFsUploadErrors, PostBotsByBotIdContainerFsUploadResponse, PostBotsByBotIdContainerFsUploadResponses, PostBotsByBotIdContainerResponse, PostBotsByBotIdContainerResponses, PostBotsByBotIdContainerSkillsData, PostBotsByBotIdContainerSkillsError, PostBotsByBotIdContainerSkillsErrors, PostBotsByBotIdContainerSkillsResponse, PostBotsByBotIdContainerSkillsResponses, PostBotsByBotIdContainerSnapshotsData, PostBotsByBotIdContainerSnapshotsError, PostBotsByBotIdContainerSnapshotsErrors, PostBotsByBotIdContainerSnapshotsResponse, PostBotsByBotIdContainerSnapshotsResponses, PostBotsByBotIdContainerStartData, PostBotsByBotIdContainerStartError, PostBotsByBotIdContainerStartErrors, PostBotsByBotIdContainerStartResponse, PostBotsByBotIdContainerStartResponses, PostBotsByBotIdContainerStopData, PostBotsByBotIdContainerStopError, PostBotsByBotIdContainerStopErrors, PostBotsByBotIdContainerStopResponse, PostBotsByBotIdContainerStopResponses, PostBotsByBotIdHistoryData, PostBotsByBotIdHistoryError, PostBotsByBotIdHistoryErrors, PostBotsByBotIdHistoryResponse, PostBotsByBotIdHistoryResponses, PostBotsByBotIdMcpData, PostBotsByBotIdMcpError, PostBotsByBotIdMcpErrors, PostBotsByBotIdMcpResponse, PostBotsByBotIdMcpResponses, PostBotsByBotIdMcpStdioBySessionIdData, PostBotsByBotIdMcpStdioBySessionIdError, PostBotsByBotIdMcpStdioBySessionIdErrors, PostBotsByBotIdMcpStdioBySessionIdResponse, PostBotsByBotIdMcpStdioBySessionIdResponses, PostBotsByBotIdMcpStdioData, PostBotsByBotIdMcpStdioError, PostBotsByBotIdMcpStdioErrors, PostBotsByBotIdMcpStdioResponse, PostBotsByBotIdMcpStdioResponses, PostBotsByBotIdMemoryAddData, PostBotsByBotIdMemoryAddError, PostBotsByBotIdMemoryAddErrors, PostBotsByBotIdMemoryAddResponse, PostBotsByBotIdMemoryAddResponses, PostBotsByBotIdMemoryEmbedData, PostBotsByBotIdMemoryEmbedError, PostBotsByBotIdMemoryEmbedErrors, PostBotsByBotIdMemoryEmbedResponse, PostBotsByBotIdMemoryEmbedResponses, PostBotsByBotIdMemorySearchData, PostBotsByBotIdMemorySearchError, PostBotsByBotIdMemorySearchErrors, PostBotsByBotIdMemorySearchResponse, PostBotsByBotIdMemorySearchResponses, PostBotsByBotIdMemoryUpdateData, PostBotsByBotIdMemoryUpdateError, PostBotsByBotIdMemoryUpdateErrors, PostBotsByBotIdMemoryUpdateResponse, PostBotsByBotIdMemoryUpdateResponses, PostBotsByBotIdScheduleData, PostBotsByBotIdScheduleError, PostBotsByBotIdScheduleErrors, PostBotsByBotIdScheduleResponse, PostBotsByBotIdScheduleResponses, PostBotsByBotIdSettingsData, PostBotsByBotIdSettingsError, PostBotsByBotIdSettingsErrors, PostBotsByBotIdSettingsResponse, PostBotsByBotIdSettingsResponses, PostBotsByBotIdSubagentsByIdSkillsData, PostBotsByBotIdSubagentsByIdSkillsError, PostBotsByBotIdSubagentsByIdSkillsErrors, PostBotsByBotIdSubagentsByIdSkillsResponse, PostBotsByBotIdSubagentsByIdSkillsResponses, PostBotsByBotIdSubagentsData, PostBotsByBotIdSubagentsError, PostBotsByBotIdSubagentsErrors, PostBotsByBotIdSubagentsResponse, PostBotsByBotIdSubagentsResponses, PostBotsByIdChannelByPlatformSendData, PostBotsByIdChannelByPlatformSendError, PostBotsByIdChannelByPlatformSendErrors, PostBotsByIdChannelByPlatformSendResponse, PostBotsByIdChannelByPlatformSendResponses, PostBotsByIdChannelByPlatformSendSessionData, PostBotsByIdChannelByPlatformSendSessionError, PostBotsByIdChannelByPlatformSendSessionErrors, PostBotsByIdChannelByPlatformSendSessionResponse, PostBotsByIdChannelByPlatformSendSessionResponses, PostBotsData, PostBotsError, PostBotsErrors, PostBotsResponse, PostBotsResponses, PostEmbeddingsData, PostEmbeddingsError, PostEmbeddingsErrors, PostEmbeddingsResponse, PostEmbeddingsResponses, PostModelsData, PostModelsEnableData, PostModelsEnableError, PostModelsEnableErrors, PostModelsEnableResponse, PostModelsEnableResponses, PostModelsError, PostModelsErrors, PostModelsResponse, PostModelsResponses, PostProvidersData, PostProvidersError, PostProvidersErrors, PostProvidersResponse, PostProvidersResponses, PostUsersData, PostUsersError, PostUsersErrors, PostUsersResponse, PostUsersResponses, ProvidersClientType, ProvidersCountResponse, ProvidersCreateRequest, ProvidersGetResponse, ProvidersUpdateRequest, PutBotsByBotIdMcpByIdData, PutBotsByBotIdMcpByIdError, PutBotsByBotIdMcpByIdErrors, PutBotsByBotIdMcpByIdResponse, PutBotsByBotIdMcpByIdResponses, PutBotsByBotIdScheduleByIdData, PutBotsByBotIdScheduleByIdError, PutBotsByBotIdScheduleByIdErrors, PutBotsByBotIdScheduleByIdResponse, PutBotsByBotIdScheduleByIdResponses, PutBotsByBotIdSettingsData, PutBotsByBotIdSettingsError, PutBotsByBotIdSettingsErrors, PutBotsByBotIdSettingsResponse, PutBotsByBotIdSettingsResponses, PutBotsByBotIdSubagentsByIdContextData, PutBotsByBotIdSubagentsByIdContextError, PutBotsByBotIdSubagentsByIdContextErrors, PutBotsByBotIdSubagentsByIdContextResponse, PutBotsByBotIdSubagentsByIdContextResponses, PutBotsByBotIdSubagentsByIdData, PutBotsByBotIdSubagentsByIdError, PutBotsByBotIdSubagentsByIdErrors, PutBotsByBotIdSubagentsByIdResponse, PutBotsByBotIdSubagentsByIdResponses, PutBotsByBotIdSubagentsByIdSkillsData, PutBotsByBotIdSubagentsByIdSkillsError, PutBotsByBotIdSubagentsByIdSkillsErrors, PutBotsByBotIdSubagentsByIdSkillsResponse, PutBotsByBotIdSubagentsByIdSkillsResponses, PutBotsByIdChannelByPlatformData, PutBotsByIdChannelByPlatformError, PutBotsByIdChannelByPlatformErrors, PutBotsByIdChannelByPlatformResponse, PutBotsByIdChannelByPlatformResponses, PutBotsByIdData, PutBotsByIdError, PutBotsByIdErrors, PutBotsByIdMembersData, PutBotsByIdMembersError, PutBotsByIdMembersErrors, PutBotsByIdMembersResponse, PutBotsByIdMembersResponses, PutBotsByIdOwnerData, PutBotsByIdOwnerError, PutBotsByIdOwnerErrors, PutBotsByIdOwnerResponse, PutBotsByIdOwnerResponses, PutBotsByIdResponse, PutBotsByIdResponses, PutModelsByIdData, PutModelsByIdError, PutModelsByIdErrors, PutModelsByIdResponse, PutModelsByIdResponses, PutModelsModelByModelIdData, PutModelsModelByModelIdError, PutModelsModelByModelIdErrors, PutModelsModelByModelIdResponse, PutModelsModelByModelIdResponses, PutProvidersByIdData, PutProvidersByIdError, PutProvidersByIdErrors, PutProvidersByIdResponse, PutProvidersByIdResponses, PutUsersByIdData, PutUsersByIdError, PutUsersByIdErrors, PutUsersByIdPasswordData, PutUsersByIdPasswordError, PutUsersByIdPasswordErrors, PutUsersByIdPasswordResponses, PutUsersByIdResponse, PutUsersByIdResponses, PutUsersMeChannelsByPlatformData, PutUsersMeChannelsByPlatformError, PutUsersMeChannelsByPlatformErrors, PutUsersMeChannelsByPlatformResponse, PutUsersMeChannelsByPlatformResponses, PutUsersMeData, PutUsersMeError, PutUsersMeErrors, PutUsersMePasswordData, PutUsersMePasswordError, PutUsersMePasswordErrors, PutUsersMePasswordResponses, PutUsersMeResponse, PutUsersMeResponses, ScheduleCreateRequest, ScheduleListResponse, ScheduleNullableInt, ScheduleSchedule, ScheduleUpdateRequest, SettingsSettings, SettingsUpsertRequest, SubagentAddSkillsRequest, SubagentContextResponse, SubagentCreateRequest, SubagentListResponse, SubagentSkillsResponse, SubagentSubagent, SubagentUpdateContextRequest, SubagentUpdateRequest, SubagentUpdateSkillsRequest, UsersCreateUserRequest, UsersListUsersResponse, UsersResetPasswordRequest, UsersUpdatePasswordRequest, UsersUpdateProfileRequest, UsersUpdateUserRequest, UsersUser } from './types.gen'; diff --git a/packages/sdk/src/sdk.gen.ts b/packages/sdk/src/sdk.gen.ts new file mode 100644 index 00000000..44e22042 --- /dev/null +++ b/packages/sdk/src/sdk.gen.ts @@ -0,0 +1,1075 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Client, Options as Options2, TDataShape } from './client'; +import { client } from './client.gen'; +import type { DeleteBotsByBotIdContainerData, DeleteBotsByBotIdContainerErrors, DeleteBotsByBotIdContainerFsData, DeleteBotsByBotIdContainerFsErrors, DeleteBotsByBotIdContainerFsResponses, DeleteBotsByBotIdContainerResponses, DeleteBotsByBotIdContainerSkillsData, DeleteBotsByBotIdContainerSkillsErrors, DeleteBotsByBotIdContainerSkillsResponses, DeleteBotsByBotIdHistoryByIdData, DeleteBotsByBotIdHistoryByIdErrors, DeleteBotsByBotIdHistoryByIdResponses, DeleteBotsByBotIdHistoryData, DeleteBotsByBotIdHistoryErrors, DeleteBotsByBotIdHistoryResponses, DeleteBotsByBotIdMcpByIdData, DeleteBotsByBotIdMcpByIdErrors, DeleteBotsByBotIdMcpByIdResponses, DeleteBotsByBotIdMemoryMemoriesByMemoryIdData, DeleteBotsByBotIdMemoryMemoriesByMemoryIdErrors, DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponses, DeleteBotsByBotIdMemoryMemoriesData, DeleteBotsByBotIdMemoryMemoriesErrors, DeleteBotsByBotIdMemoryMemoriesResponses, DeleteBotsByBotIdScheduleByIdData, DeleteBotsByBotIdScheduleByIdErrors, DeleteBotsByBotIdScheduleByIdResponses, DeleteBotsByBotIdSettingsData, DeleteBotsByBotIdSettingsErrors, DeleteBotsByBotIdSettingsResponses, DeleteBotsByBotIdSubagentsByIdData, DeleteBotsByBotIdSubagentsByIdErrors, DeleteBotsByBotIdSubagentsByIdResponses, DeleteBotsByIdData, DeleteBotsByIdErrors, DeleteBotsByIdMembersByUserIdData, DeleteBotsByIdMembersByUserIdErrors, DeleteBotsByIdMembersByUserIdResponses, DeleteBotsByIdResponses, DeleteModelsByIdData, DeleteModelsByIdErrors, DeleteModelsByIdResponses, DeleteModelsModelByModelIdData, DeleteModelsModelByModelIdErrors, DeleteModelsModelByModelIdResponses, DeleteProvidersByIdData, DeleteProvidersByIdErrors, DeleteProvidersByIdResponses, GetBotsByBotIdContainerData, GetBotsByBotIdContainerErrors, GetBotsByBotIdContainerFsData, GetBotsByBotIdContainerFsErrors, GetBotsByBotIdContainerFsFileData, GetBotsByBotIdContainerFsFileErrors, GetBotsByBotIdContainerFsFileResponses, GetBotsByBotIdContainerFsResponses, GetBotsByBotIdContainerFsStatData, GetBotsByBotIdContainerFsStatErrors, GetBotsByBotIdContainerFsStatResponses, GetBotsByBotIdContainerFsUsageData, GetBotsByBotIdContainerFsUsageErrors, GetBotsByBotIdContainerFsUsageResponses, GetBotsByBotIdContainerResponses, GetBotsByBotIdContainerSkillsData, GetBotsByBotIdContainerSkillsErrors, GetBotsByBotIdContainerSkillsResponses, GetBotsByBotIdContainerSnapshotsData, GetBotsByBotIdContainerSnapshotsResponses, GetBotsByBotIdHistoryByIdData, GetBotsByBotIdHistoryByIdErrors, GetBotsByBotIdHistoryByIdResponses, GetBotsByBotIdHistoryData, GetBotsByBotIdHistoryErrors, GetBotsByBotIdHistoryResponses, GetBotsByBotIdMcpByIdData, GetBotsByBotIdMcpByIdErrors, GetBotsByBotIdMcpByIdResponses, GetBotsByBotIdMcpData, GetBotsByBotIdMcpErrors, GetBotsByBotIdMcpResponses, GetBotsByBotIdMemoryMemoriesByMemoryIdData, GetBotsByBotIdMemoryMemoriesByMemoryIdErrors, GetBotsByBotIdMemoryMemoriesByMemoryIdResponses, GetBotsByBotIdMemoryMemoriesData, GetBotsByBotIdMemoryMemoriesErrors, GetBotsByBotIdMemoryMemoriesResponses, GetBotsByBotIdScheduleByIdData, GetBotsByBotIdScheduleByIdErrors, GetBotsByBotIdScheduleByIdResponses, GetBotsByBotIdScheduleData, GetBotsByBotIdScheduleErrors, GetBotsByBotIdScheduleResponses, GetBotsByBotIdSettingsData, GetBotsByBotIdSettingsErrors, GetBotsByBotIdSettingsResponses, GetBotsByBotIdSubagentsByIdContextData, GetBotsByBotIdSubagentsByIdContextErrors, GetBotsByBotIdSubagentsByIdContextResponses, GetBotsByBotIdSubagentsByIdData, GetBotsByBotIdSubagentsByIdErrors, GetBotsByBotIdSubagentsByIdResponses, GetBotsByBotIdSubagentsByIdSkillsData, GetBotsByBotIdSubagentsByIdSkillsErrors, GetBotsByBotIdSubagentsByIdSkillsResponses, GetBotsByBotIdSubagentsData, GetBotsByBotIdSubagentsErrors, GetBotsByBotIdSubagentsResponses, GetBotsByIdChannelByPlatformData, GetBotsByIdChannelByPlatformErrors, GetBotsByIdChannelByPlatformResponses, GetBotsByIdData, GetBotsByIdErrors, GetBotsByIdMembersData, GetBotsByIdMembersErrors, GetBotsByIdMembersResponses, GetBotsByIdResponses, GetBotsData, GetBotsErrors, GetBotsResponses, GetChannelsByPlatformData, GetChannelsByPlatformErrors, GetChannelsByPlatformResponses, GetChannelsData, GetChannelsErrors, GetChannelsResponses, GetModelsByIdData, GetModelsByIdErrors, GetModelsByIdResponses, GetModelsCountData, GetModelsCountErrors, GetModelsCountResponses, GetModelsData, GetModelsErrors, GetModelsModelByModelIdData, GetModelsModelByModelIdErrors, GetModelsModelByModelIdResponses, GetModelsResponses, GetProvidersByIdData, GetProvidersByIdErrors, GetProvidersByIdModelsData, GetProvidersByIdModelsErrors, GetProvidersByIdModelsResponses, GetProvidersByIdResponses, GetProvidersCountData, GetProvidersCountErrors, GetProvidersCountResponses, GetProvidersData, GetProvidersErrors, GetProvidersNameByNameData, GetProvidersNameByNameErrors, GetProvidersNameByNameResponses, GetProvidersResponses, GetUsersByIdData, GetUsersByIdErrors, GetUsersByIdResponses, GetUsersData, GetUsersErrors, GetUsersMeChannelsByPlatformData, GetUsersMeChannelsByPlatformErrors, GetUsersMeChannelsByPlatformResponses, GetUsersMeData, GetUsersMeErrors, GetUsersMeResponses, GetUsersResponses, PostAuthLoginData, PostAuthLoginErrors, PostAuthLoginResponses, PostBotsByBotIdChatData, PostBotsByBotIdChatErrors, PostBotsByBotIdChatResponses, PostBotsByBotIdChatStreamData, PostBotsByBotIdChatStreamErrors, PostBotsByBotIdChatStreamResponses, PostBotsByBotIdContainerData, PostBotsByBotIdContainerErrors, PostBotsByBotIdContainerFsDirData, PostBotsByBotIdContainerFsDirErrors, PostBotsByBotIdContainerFsDirResponses, PostBotsByBotIdContainerFsFileData, PostBotsByBotIdContainerFsFileErrors, PostBotsByBotIdContainerFsFileResponses, PostBotsByBotIdContainerFsMcpData, PostBotsByBotIdContainerFsMcpErrors, PostBotsByBotIdContainerFsMcpResponses, PostBotsByBotIdContainerFsUploadData, PostBotsByBotIdContainerFsUploadErrors, PostBotsByBotIdContainerFsUploadResponses, PostBotsByBotIdContainerResponses, PostBotsByBotIdContainerSkillsData, PostBotsByBotIdContainerSkillsErrors, PostBotsByBotIdContainerSkillsResponses, PostBotsByBotIdContainerSnapshotsData, PostBotsByBotIdContainerSnapshotsErrors, PostBotsByBotIdContainerSnapshotsResponses, PostBotsByBotIdContainerStartData, PostBotsByBotIdContainerStartErrors, PostBotsByBotIdContainerStartResponses, PostBotsByBotIdContainerStopData, PostBotsByBotIdContainerStopErrors, PostBotsByBotIdContainerStopResponses, PostBotsByBotIdHistoryData, PostBotsByBotIdHistoryErrors, PostBotsByBotIdHistoryResponses, PostBotsByBotIdMcpData, PostBotsByBotIdMcpErrors, PostBotsByBotIdMcpResponses, PostBotsByBotIdMcpStdioBySessionIdData, PostBotsByBotIdMcpStdioBySessionIdErrors, PostBotsByBotIdMcpStdioBySessionIdResponses, PostBotsByBotIdMcpStdioData, PostBotsByBotIdMcpStdioErrors, PostBotsByBotIdMcpStdioResponses, PostBotsByBotIdMemoryAddData, PostBotsByBotIdMemoryAddErrors, PostBotsByBotIdMemoryAddResponses, PostBotsByBotIdMemoryEmbedData, PostBotsByBotIdMemoryEmbedErrors, PostBotsByBotIdMemoryEmbedResponses, PostBotsByBotIdMemorySearchData, PostBotsByBotIdMemorySearchErrors, PostBotsByBotIdMemorySearchResponses, PostBotsByBotIdMemoryUpdateData, PostBotsByBotIdMemoryUpdateErrors, PostBotsByBotIdMemoryUpdateResponses, PostBotsByBotIdScheduleData, PostBotsByBotIdScheduleErrors, PostBotsByBotIdScheduleResponses, PostBotsByBotIdSettingsData, PostBotsByBotIdSettingsErrors, PostBotsByBotIdSettingsResponses, PostBotsByBotIdSubagentsByIdSkillsData, PostBotsByBotIdSubagentsByIdSkillsErrors, PostBotsByBotIdSubagentsByIdSkillsResponses, PostBotsByBotIdSubagentsData, PostBotsByBotIdSubagentsErrors, PostBotsByBotIdSubagentsResponses, PostBotsByIdChannelByPlatformSendData, PostBotsByIdChannelByPlatformSendErrors, PostBotsByIdChannelByPlatformSendResponses, PostBotsByIdChannelByPlatformSendSessionData, PostBotsByIdChannelByPlatformSendSessionErrors, PostBotsByIdChannelByPlatformSendSessionResponses, PostBotsData, PostBotsErrors, PostBotsResponses, PostEmbeddingsData, PostEmbeddingsErrors, PostEmbeddingsResponses, PostModelsData, PostModelsEnableData, PostModelsEnableErrors, PostModelsEnableResponses, PostModelsErrors, PostModelsResponses, PostProvidersData, PostProvidersErrors, PostProvidersResponses, PostUsersData, PostUsersErrors, PostUsersResponses, PutBotsByBotIdMcpByIdData, PutBotsByBotIdMcpByIdErrors, PutBotsByBotIdMcpByIdResponses, PutBotsByBotIdScheduleByIdData, PutBotsByBotIdScheduleByIdErrors, PutBotsByBotIdScheduleByIdResponses, PutBotsByBotIdSettingsData, PutBotsByBotIdSettingsErrors, PutBotsByBotIdSettingsResponses, PutBotsByBotIdSubagentsByIdContextData, PutBotsByBotIdSubagentsByIdContextErrors, PutBotsByBotIdSubagentsByIdContextResponses, PutBotsByBotIdSubagentsByIdData, PutBotsByBotIdSubagentsByIdErrors, PutBotsByBotIdSubagentsByIdResponses, PutBotsByBotIdSubagentsByIdSkillsData, PutBotsByBotIdSubagentsByIdSkillsErrors, PutBotsByBotIdSubagentsByIdSkillsResponses, PutBotsByIdChannelByPlatformData, PutBotsByIdChannelByPlatformErrors, PutBotsByIdChannelByPlatformResponses, PutBotsByIdData, PutBotsByIdErrors, PutBotsByIdMembersData, PutBotsByIdMembersErrors, PutBotsByIdMembersResponses, PutBotsByIdOwnerData, PutBotsByIdOwnerErrors, PutBotsByIdOwnerResponses, PutBotsByIdResponses, PutModelsByIdData, PutModelsByIdErrors, PutModelsByIdResponses, PutModelsModelByModelIdData, PutModelsModelByModelIdErrors, PutModelsModelByModelIdResponses, PutProvidersByIdData, PutProvidersByIdErrors, PutProvidersByIdResponses, PutUsersByIdData, PutUsersByIdErrors, PutUsersByIdPasswordData, PutUsersByIdPasswordErrors, PutUsersByIdPasswordResponses, PutUsersByIdResponses, PutUsersMeChannelsByPlatformData, PutUsersMeChannelsByPlatformErrors, PutUsersMeChannelsByPlatformResponses, PutUsersMeData, PutUsersMeErrors, PutUsersMePasswordData, PutUsersMePasswordErrors, PutUsersMePasswordResponses, PutUsersMeResponses } from './types.gen'; + +export type Options = Options2 & { + /** + * You can provide a client instance returned by `createClient()` instead of + * individual options. This might be also useful if you want to implement a + * custom client. + */ + client?: Client; + /** + * You can pass arbitrary values through the `meta` object. This can be + * used to access values that aren't defined as part of the SDK function. + */ + meta?: Record; +}; + +/** + * Login + * + * Validate user credentials and issue a JWT + */ +export const postAuthLogin = (options: Options) => (options.client ?? client).post({ + url: '/auth/login', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List bots + * + * List bots accessible to current user (admin can specify owner_id) + */ +export const getBots = (options?: Options) => (options?.client ?? client).get({ url: '/bots', ...options }); + +/** + * Create bot user + * + * Create a bot user owned by current user (or admin-specified owner) + */ +export const postBots = (options: Options) => (options.client ?? client).post({ + url: '/bots', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Chat with AI + * + * Send a chat message and get a response. The system will automatically select an appropriate chat model from the database. + */ +export const postBotsByBotIdChat = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/chat', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Stream chat with AI + * + * Send a chat message and get a streaming response. The system will automatically select an appropriate chat model from the database. + */ +export const postBotsByBotIdChatStream = (options: Options) => (options.client ?? client).sse.post({ + url: '/bots/{bot_id}/chat/stream', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete MCP container for bot + */ +export const deleteBotsByBotIdContainer = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/container', ...options }); + +/** + * Get container info for bot + */ +export const getBotsByBotIdContainer = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container', ...options }); + +/** + * Create and start MCP container for bot + */ +export const postBotsByBotIdContainer = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete a file or directory + */ +export const deleteBotsByBotIdContainerFs = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/container/fs', ...options }); + +/** + * List files for a bot + * + * List entries under a relative path + */ +export const getBotsByBotIdContainerFs = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/fs', ...options }); + +/** + * MCP filesystem tools (JSON-RPC) + * + * Forwards MCP JSON-RPC requests to the MCP server inside the container. + * Required: + * - container task is running + * - container has data mount (default /data) bound to /users/ + * - container image contains the "mcp" binary + * Auth: Bearer JWT is used to determine user_id (sub or user_id). + * Paths must be relative (no leading slash) and must not contain "..". + * + * Example: tools/list + * {"jsonrpc":"2.0","id":1,"method":"tools/list"} + * + * Example: tools/call (fs.read) + * {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"fs.read","arguments":{"path":"notes.txt"}}} + */ +export const postBotsByBotIdContainerFsMcp = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container/fs-mcp', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Create a directory + */ +export const postBotsByBotIdContainerFsDir = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container/fs/dir', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Read file content + */ +export const getBotsByBotIdContainerFsFile = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/fs/file', ...options }); + +/** + * Create or overwrite a file + */ +export const postBotsByBotIdContainerFsFile = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container/fs/file', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get file or directory metadata + */ +export const getBotsByBotIdContainerFsStat = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/fs/stat', ...options }); + +/** + * Upload a file + */ +export const postBotsByBotIdContainerFsUpload = (options: Options) => (options.client ?? client).post({ url: '/bots/{bot_id}/container/fs/upload', ...options }); + +/** + * Get usage under a path + */ +export const getBotsByBotIdContainerFsUsage = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/fs/usage', ...options }); + +/** + * Delete skills from data directory + */ +export const deleteBotsByBotIdContainerSkills = (options: Options) => (options.client ?? client).delete({ + url: '/bots/{bot_id}/container/skills', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List skills from data directory + */ +export const getBotsByBotIdContainerSkills = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/skills', ...options }); + +/** + * Upload skills into data directory + */ +export const postBotsByBotIdContainerSkills = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container/skills', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List snapshots + */ +export const getBotsByBotIdContainerSnapshots = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/container/snapshots', ...options }); + +/** + * Create container snapshot for bot + */ +export const postBotsByBotIdContainerSnapshots = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/container/snapshots', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Start container task for bot + */ +export const postBotsByBotIdContainerStart = (options: Options) => (options.client ?? client).post({ url: '/bots/{bot_id}/container/start', ...options }); + +/** + * Stop container task for bot + */ +export const postBotsByBotIdContainerStop = (options: Options) => (options.client ?? client).post({ url: '/bots/{bot_id}/container/stop', ...options }); + +/** + * Delete all history records + * + * Delete all history records for current user + */ +export const deleteBotsByBotIdHistory = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/history', ...options }); + +/** + * List history records + * + * List history records for current user + */ +export const getBotsByBotIdHistory = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/history', ...options }); + +/** + * Create history record + * + * Create a history record for current user + */ +export const postBotsByBotIdHistory = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/history', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete history record + * + * Delete a history record by ID (must belong to current user) + */ +export const deleteBotsByBotIdHistoryById = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/history/{id}', ...options }); + +/** + * Get history record + * + * Get a history record by ID (must belong to current user) + */ +export const getBotsByBotIdHistoryById = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/history/{id}', ...options }); + +/** + * List MCP connections + * + * List MCP connections for a bot + */ +export const getBotsByBotIdMcp = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/mcp', ...options }); + +/** + * Create MCP connection + * + * Create a MCP connection for a bot + */ +export const postBotsByBotIdMcp = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/mcp', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Create MCP stdio proxy + * + * Start a stdio MCP process in the bot container and expose it as MCP HTTP endpoint. + */ +export const postBotsByBotIdMcpStdio = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/mcp-stdio', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * MCP stdio proxy (JSON-RPC) + * + * Proxies MCP JSON-RPC requests to a stdio MCP process in the container. + */ +export const postBotsByBotIdMcpStdioBySessionId = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/mcp-stdio/{session_id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete MCP connection + * + * Delete a MCP connection by ID + */ +export const deleteBotsByBotIdMcpById = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/mcp/{id}', ...options }); + +/** + * Get MCP connection + * + * Get a MCP connection by ID + */ +export const getBotsByBotIdMcpById = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/mcp/{id}', ...options }); + +/** + * Update MCP connection + * + * Update a MCP connection by ID + */ +export const putBotsByBotIdMcpById = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/mcp/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Add memory + * + * Add memory for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryAdd = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/memory/add', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Embed and upsert memory + * + * Embed text or multimodal input and upsert into memory store. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryEmbed = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/memory/embed', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete memories + * + * Delete all memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const deleteBotsByBotIdMemoryMemories = (options: Options) => (options.client ?? client).delete({ + url: '/bots/{bot_id}/memory/memories', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List memories + * + * List memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const getBotsByBotIdMemoryMemories = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/memory/memories', ...options }); + +/** + * Delete memory + * + * Delete a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const deleteBotsByBotIdMemoryMemoriesByMemoryId = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/memory/memories/{memoryId}', ...options }); + +/** + * Get memory + * + * Get a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const getBotsByBotIdMemoryMemoriesByMemoryId = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/memory/memories/{memoryId}', ...options }); + +/** + * Search memories + * + * Search memories for a user via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemorySearch = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/memory/search', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Update memory + * + * Update a memory by ID via memory. Auth: Bearer JWT determines user_id (sub or user_id). + */ +export const postBotsByBotIdMemoryUpdate = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/memory/update', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List schedules + * + * List schedules for current user + */ +export const getBotsByBotIdSchedule = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/schedule', ...options }); + +/** + * Create schedule + * + * Create a schedule for current user + */ +export const postBotsByBotIdSchedule = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/schedule', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete schedule + * + * Delete a schedule by ID + */ +export const deleteBotsByBotIdScheduleById = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/schedule/{id}', ...options }); + +/** + * Get schedule + * + * Get a schedule by ID + */ +export const getBotsByBotIdScheduleById = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/schedule/{id}', ...options }); + +/** + * Update schedule + * + * Update a schedule by ID + */ +export const putBotsByBotIdScheduleById = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/schedule/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete user settings + * + * Remove agent settings for current user + */ +export const deleteBotsByBotIdSettings = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/settings', ...options }); + +/** + * Get user settings + * + * Get agent settings for current user + */ +export const getBotsByBotIdSettings = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/settings', ...options }); + +/** + * Update user settings + * + * Update or create agent settings for current user + */ +export const postBotsByBotIdSettings = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/settings', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Update user settings + * + * Update or create agent settings for current user + */ +export const putBotsByBotIdSettings = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/settings', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List subagents + * + * List subagents for current user + */ +export const getBotsByBotIdSubagents = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/subagents', ...options }); + +/** + * Create subagent + * + * Create a subagent for current user + */ +export const postBotsByBotIdSubagents = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/subagents', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete subagent + * + * Delete a subagent by ID + */ +export const deleteBotsByBotIdSubagentsById = (options: Options) => (options.client ?? client).delete({ url: '/bots/{bot_id}/subagents/{id}', ...options }); + +/** + * Get subagent + * + * Get a subagent by ID + */ +export const getBotsByBotIdSubagentsById = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/subagents/{id}', ...options }); + +/** + * Update subagent + * + * Update a subagent by ID + */ +export const putBotsByBotIdSubagentsById = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/subagents/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get subagent context + * + * Get a subagent's message context + */ +export const getBotsByBotIdSubagentsByIdContext = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/subagents/{id}/context', ...options }); + +/** + * Update subagent context + * + * Update a subagent's message context + */ +export const putBotsByBotIdSubagentsByIdContext = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/subagents/{id}/context', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get subagent skills + * + * Get a subagent's skills + */ +export const getBotsByBotIdSubagentsByIdSkills = (options: Options) => (options.client ?? client).get({ url: '/bots/{bot_id}/subagents/{id}/skills', ...options }); + +/** + * Add subagent skills + * + * Add skills to a subagent + */ +export const postBotsByBotIdSubagentsByIdSkills = (options: Options) => (options.client ?? client).post({ + url: '/bots/{bot_id}/subagents/{id}/skills', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Update subagent skills + * + * Replace a subagent's skills + */ +export const putBotsByBotIdSubagentsByIdSkills = (options: Options) => (options.client ?? client).put({ + url: '/bots/{bot_id}/subagents/{id}/skills', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete bot + * + * Delete a bot user (owner/admin only) + */ +export const deleteBotsById = (options: Options) => (options.client ?? client).delete({ url: '/bots/{id}', ...options }); + +/** + * Get bot details + * + * Get a bot by ID (owner/admin only) + */ +export const getBotsById = (options: Options) => (options.client ?? client).get({ url: '/bots/{id}', ...options }); + +/** + * Update bot details + * + * Update bot profile (owner/admin only) + */ +export const putBotsById = (options: Options) => (options.client ?? client).put({ + url: '/bots/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get bot channel config + * + * Get bot channel configuration + */ +export const getBotsByIdChannelByPlatform = (options: Options) => (options.client ?? client).get({ url: '/bots/{id}/channel/{platform}', ...options }); + +/** + * Update bot channel config + * + * Update bot channel configuration + */ +export const putBotsByIdChannelByPlatform = (options: Options) => (options.client ?? client).put({ + url: '/bots/{id}/channel/{platform}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Send message via bot channel + * + * Send a message using bot channel configuration + */ +export const postBotsByIdChannelByPlatformSend = (options: Options) => (options.client ?? client).post({ + url: '/bots/{id}/channel/{platform}/send', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Send message via bot channel session token + * + * Send a message using a session-scoped token (reply only) + */ +export const postBotsByIdChannelByPlatformSendSession = (options: Options) => (options.client ?? client).post({ + url: '/bots/{id}/channel/{platform}/send_session', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List bot members + * + * List members for a bot + */ +export const getBotsByIdMembers = (options: Options) => (options.client ?? client).get({ url: '/bots/{id}/members', ...options }); + +/** + * Upsert bot member + * + * Add or update bot member role + */ +export const putBotsByIdMembers = (options: Options) => (options.client ?? client).put({ + url: '/bots/{id}/members', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete bot member + * + * Remove a member from a bot + */ +export const deleteBotsByIdMembersByUserId = (options: Options) => (options.client ?? client).delete({ url: '/bots/{id}/members/{user_id}', ...options }); + +/** + * Transfer bot owner (admin only) + * + * Transfer bot ownership to another human user + */ +export const putBotsByIdOwner = (options: Options) => (options.client ?? client).put({ + url: '/bots/{id}/owner', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List channel capabilities and schemas + * + * List channel meta information including capabilities and schemas + */ +export const getChannels = (options?: Options) => (options?.client ?? client).get({ url: '/channels', ...options }); + +/** + * Get channel capabilities and schemas + * + * Get channel meta information including capabilities and schemas + */ +export const getChannelsByPlatform = (options: Options) => (options.client ?? client).get({ url: '/channels/{platform}', ...options }); + +/** + * Create embeddings + * + * Create text or multimodal embeddings + */ +export const postEmbeddings = (options: Options) => (options.client ?? client).post({ + url: '/embeddings', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List all models + * + * Get a list of all configured models, optionally filtered by type or client type + */ +export const getModels = (options?: Options) => (options?.client ?? client).get({ url: '/models', ...options }); + +/** + * Create a new model + * + * Create a new model configuration + */ +export const postModels = (options: Options) => (options.client ?? client).post({ + url: '/models', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get model count + * + * Get the total count of models, optionally filtered by type + */ +export const getModelsCount = (options?: Options) => (options?.client ?? client).get({ url: '/models/count', ...options }); + +/** + * Enable model for chat/memory/embedding + * + * Update the current user's settings to use the selected model + */ +export const postModelsEnable = (options: Options) => (options.client ?? client).post({ + url: '/models/enable', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete model by model ID + * + * Delete a model configuration by its model_id field (e.g., gpt-4) + */ +export const deleteModelsModelByModelId = (options: Options) => (options.client ?? client).delete({ url: '/models/model/{modelId}', ...options }); + +/** + * Get model by model ID + * + * Get a model configuration by its model_id field (e.g., gpt-4) + */ +export const getModelsModelByModelId = (options: Options) => (options.client ?? client).get({ url: '/models/model/{modelId}', ...options }); + +/** + * Update model by model ID + * + * Update a model configuration by its model_id field (e.g., gpt-4) + */ +export const putModelsModelByModelId = (options: Options) => (options.client ?? client).put({ + url: '/models/model/{modelId}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Delete model by internal ID + * + * Delete a model configuration by its internal UUID + */ +export const deleteModelsById = (options: Options) => (options.client ?? client).delete({ url: '/models/{id}', ...options }); + +/** + * Get model by internal ID + * + * Get a model configuration by its internal UUID + */ +export const getModelsById = (options: Options) => (options.client ?? client).get({ url: '/models/{id}', ...options }); + +/** + * Update model by internal ID + * + * Update a model configuration by its internal UUID + */ +export const putModelsById = (options: Options) => (options.client ?? client).put({ + url: '/models/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List all LLM providers + * + * Get a list of all configured LLM providers, optionally filtered by client type + */ +export const getProviders = (options?: Options) => (options?.client ?? client).get({ url: '/providers', ...options }); + +/** + * Create a new LLM provider + * + * Create a new LLM provider configuration + */ +export const postProviders = (options: Options) => (options.client ?? client).post({ + url: '/providers', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Count providers + * + * Get the total count of providers, optionally filtered by client type + */ +export const getProvidersCount = (options?: Options) => (options?.client ?? client).get({ url: '/providers/count', ...options }); + +/** + * Get provider by name + * + * Get a provider configuration by its name + */ +export const getProvidersNameByName = (options: Options) => (options.client ?? client).get({ url: '/providers/name/{name}', ...options }); + +/** + * Delete provider + * + * Delete a provider configuration + */ +export const deleteProvidersById = (options: Options) => (options.client ?? client).delete({ url: '/providers/{id}', ...options }); + +/** + * Get provider by ID + * + * Get a provider configuration by its ID + */ +export const getProvidersById = (options: Options) => (options.client ?? client).get({ url: '/providers/{id}', ...options }); + +/** + * Update provider + * + * Update an existing provider configuration + */ +export const putProvidersById = (options: Options) => (options.client ?? client).put({ + url: '/providers/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * List provider models + * + * Get models for a provider by id, optionally filtered by type + */ +export const getProvidersByIdModels = (options: Options) => (options.client ?? client).get({ url: '/providers/{id}/models', ...options }); + +/** + * List users (admin only) + * + * List users + */ +export const getUsers = (options?: Options) => (options?.client ?? client).get({ url: '/users', ...options }); + +/** + * Create human user (admin only) + * + * Create a new human user account + */ +export const postUsers = (options: Options) => (options.client ?? client).post({ + url: '/users', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get current user + * + * Get current user profile + */ +export const getUsersMe = (options?: Options) => (options?.client ?? client).get({ url: '/users/me', ...options }); + +/** + * Update current user profile + * + * Update current user display name or avatar + */ +export const putUsersMe = (options: Options) => (options.client ?? client).put({ + url: '/users/me', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get channel user config + * + * Get channel binding configuration for current user + */ +export const getUsersMeChannelsByPlatform = (options: Options) => (options.client ?? client).get({ url: '/users/me/channels/{platform}', ...options }); + +/** + * Update channel user config + * + * Update channel binding configuration for current user + */ +export const putUsersMeChannelsByPlatform = (options: Options) => (options.client ?? client).put({ + url: '/users/me/channels/{platform}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Update current user password + * + * Update current user password with current password check + */ +export const putUsersMePassword = (options: Options) => (options.client ?? client).put({ + url: '/users/me/password', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Get user by ID + * + * Get user details (self or admin only) + */ +export const getUsersById = (options: Options) => (options.client ?? client).get({ url: '/users/{id}', ...options }); + +/** + * Update user (admin only) + * + * Update user profile and status + */ +export const putUsersById = (options: Options) => (options.client ?? client).put({ + url: '/users/{id}', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Reset user password (admin only) + * + * Reset a user password + */ +export const putUsersByIdPassword = (options: Options) => (options.client ?? client).put({ + url: '/users/{id}/password', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); diff --git a/packages/sdk/src/types.gen.ts b/packages/sdk/src/types.gen.ts new file mode 100644 index 00000000..9a91b061 --- /dev/null +++ b/packages/sdk/src/types.gen.ts @@ -0,0 +1,5015 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: string; +}; + +export type BotsBot = { + avatar_url?: string; + created_at: string; + display_name: string; + id: string; + is_active: boolean; + metadata?: { + [key: string]: unknown; + }; + owner_user_id: string; + type: string; + updated_at: string; +}; + +export type BotsBotMember = { + bot_id?: string; + created_at?: string; + role?: string; + user_id?: string; +}; + +export type BotsCreateBotRequest = { + avatar_url?: string; + display_name?: string; + is_active?: boolean; + metadata?: { + [key: string]: unknown; + }; + type?: string; +}; + +export type BotsListBotsResponse = { + items: Array; +}; + +export type BotsListMembersResponse = { + items?: Array; +}; + +export type BotsTransferBotRequest = { + owner_user_id?: string; +}; + +export type BotsUpdateBotRequest = { + avatar_url?: string; + display_name?: string; + is_active?: boolean; + metadata?: { + [key: string]: unknown; + }; +}; + +export type BotsUpsertMemberRequest = { + role?: string; + user_id?: string; +}; + +export type ChannelAction = { + label?: string; + type?: string; + url?: string; + value?: string; +}; + +export type ChannelAttachment = { + caption?: string; + duration_ms?: number; + height?: number; + metadata?: { + [key: string]: unknown; + }; + mime?: string; + name?: string; + size?: number; + thumbnail_url?: string; + type?: ChannelAttachmentType; + url?: string; + width?: number; +}; + +export type ChannelAttachmentType = 'image' | 'audio' | 'video' | 'voice' | 'file' | 'gif'; + +export type ChannelChannelCapabilities = { + attachments?: boolean; + block_streaming?: boolean; + buttons?: boolean; + chat_types?: Array; + edit?: boolean; + markdown?: boolean; + media?: boolean; + native_commands?: boolean; + polls?: boolean; + reactions?: boolean; + reply?: boolean; + rich_text?: boolean; + streaming?: boolean; + text?: boolean; + threads?: boolean; + unsend?: boolean; +}; + +export type ChannelChannelConfig = { + botID?: string; + channelType?: string; + createdAt?: string; + credentials?: { + [key: string]: unknown; + }; + externalIdentity?: string; + id?: string; + routing?: { + [key: string]: unknown; + }; + selfIdentity?: { + [key: string]: unknown; + }; + status?: string; + updatedAt?: string; + verifiedAt?: string; +}; + +export type ChannelChannelUserBinding = { + channelType?: string; + config?: { + [key: string]: unknown; + }; + createdAt?: string; + id?: string; + updatedAt?: string; + userID?: string; +}; + +export type ChannelConfigSchema = { + fields?: { + [key: string]: ChannelFieldSchema; + }; + version?: number; +}; + +export type ChannelFieldSchema = { + description?: string; + enum?: Array; + example?: unknown; + required?: boolean; + title?: string; + type?: ChannelFieldType; +}; + +export type ChannelFieldType = 'string' | 'secret' | 'bool' | 'number' | 'enum'; + +export type ChannelMessage = { + actions?: Array; + attachments?: Array; + format?: ChannelMessageFormat; + id?: string; + metadata?: { + [key: string]: unknown; + }; + parts?: Array; + reply?: ChannelReplyRef; + text?: string; + thread?: ChannelThreadRef; +}; + +export type ChannelMessageFormat = 'plain' | 'markdown' | 'rich'; + +export type ChannelMessagePart = { + emoji?: string; + language?: string; + metadata?: { + [key: string]: unknown; + }; + styles?: Array; + text?: string; + type?: ChannelMessagePartType; + url?: string; + user_id?: string; +}; + +export type ChannelMessagePartType = 'text' | 'link' | 'code_block' | 'mention' | 'emoji'; + +export type ChannelMessageTextStyle = 'bold' | 'italic' | 'strikethrough' | 'code'; + +export type ChannelReplyRef = { + message_id?: string; + target?: string; +}; + +export type ChannelSendRequest = { + message?: ChannelMessage; + target?: string; + user_id?: string; +}; + +export type ChannelTargetHint = { + example?: string; + label?: string; +}; + +export type ChannelTargetSpec = { + format?: string; + hints?: Array; +}; + +export type ChannelThreadRef = { + id?: string; +}; + +export type ChannelUpsertConfigRequest = { + credentials?: { + [key: string]: unknown; + }; + external_identity?: string; + routing?: { + [key: string]: unknown; + }; + self_identity?: { + [key: string]: unknown; + }; + status?: string; + verified_at?: string; +}; + +export type ChannelUpsertUserConfigRequest = { + config?: { + [key: string]: unknown; + }; +}; + +export type ChatChatRequest = { + allowed_actions?: Array; + channels?: Array; + current_channel?: string; + language?: string; + max_context_load_time?: number; + messages?: Array; + model?: string; + provider?: string; + query?: string; + skills?: Array; +}; + +export type ChatChatResponse = { + messages?: Array; + model?: string; + provider?: string; + skills?: Array; +}; + +export type ChatModelMessage = { + content?: Array; + name?: string; + role?: string; + tool_call_id?: string; + tool_calls?: Array; +}; + +export type ChatToolCall = { + function?: ChatToolCallFunction; + id?: string; + type?: string; +}; + +export type ChatToolCallFunction = { + arguments?: string; + name?: string; +}; + +export type GithubComMemohaiMemohInternalMcpConnection = { + active: boolean; + bot_id: string; + config: { + [key: string]: unknown; + }; + created_at: string; + id: string; + name: string; + type: string; + updated_at: string; +}; + +export type HandlersChannelMeta = { + capabilities: ChannelChannelCapabilities; + config_schema: ChannelConfigSchema; + configless?: boolean; + display_name: string; + target_spec?: ChannelTargetSpec; + type: string; + user_config_schema?: ChannelConfigSchema; +}; + +export type HandlersCreateContainerRequest = { + image?: string; + snapshotter?: string; +}; + +export type HandlersCreateContainerResponse = { + container_id?: string; + image?: string; + snapshotter?: string; + started?: boolean; +}; + +export type HandlersCreateSnapshotRequest = { + snapshot_name?: string; +}; + +export type HandlersCreateSnapshotResponse = { + container_id?: string; + snapshot_name?: string; + snapshotter?: string; +}; + +export type HandlersEmbeddingsInput = { + image_url?: string; + text?: string; + video_url?: string; +}; + +export type HandlersEmbeddingsRequest = { + dimensions?: number; + input?: HandlersEmbeddingsInput; + model?: string; + provider?: string; + type?: string; +}; + +export type HandlersEmbeddingsResponse = { + dimensions?: number; + embedding?: Array; + message?: string; + model?: string; + provider?: string; + type?: string; + usage?: HandlersEmbeddingsUsage; +}; + +export type HandlersEmbeddingsUsage = { + image_tokens?: number; + input_tokens?: number; + video_tokens?: number; +}; + +export type HandlersEnableModelRequest = { + as?: string; + model_id?: string; +}; + +export type HandlersErrorResponse = { + message?: string; +}; + +export type HandlersFsDeleteResponse = { + ok?: boolean; +}; + +export type HandlersFsListResponse = { + entries?: Array; + path?: string; +}; + +export type HandlersFsMkdirRequest = { + parents?: boolean; + path?: string; +}; + +export type HandlersFsReadResponse = { + content?: string; + mod_time?: string; + mode?: number; + path?: string; + size?: number; +}; + +export type HandlersFsRestEntry = { + is_dir?: boolean; + mod_time?: string; + mode?: number; + path?: string; + size?: number; +}; + +export type HandlersFsStatResponse = { + is_dir?: boolean; + mod_time?: string; + mode?: number; + path?: string; + size?: number; +}; + +export type HandlersFsUsageResponse = { + dir_count?: number; + file_count?: number; + path?: string; + total_bytes?: number; +}; + +export type HandlersFsWriteRequest = { + content?: string; + overwrite?: boolean; + path?: string; +}; + +export type HandlersFsWriteResponse = { + ok?: boolean; +}; + +export type HandlersGetContainerResponse = { + container_id?: string; + container_path?: string; + created_at?: string; + host_path?: string; + image?: string; + namespace?: string; + status?: string; + task_running?: boolean; + updated_at?: string; +}; + +export type HandlersListSnapshotsResponse = { + snapshots?: Array; + snapshotter?: string; +}; + +export type HandlersLoginRequest = { + password: string; + username: string; +}; + +export type HandlersLoginResponse = { + access_token: string; + display_name: string; + expires_at: string; + role: string; + token_type: string; + user_id: string; + username: string; +}; + +export type HandlersMcpStdioRequest = { + args?: Array; + command?: string; + cwd?: string; + env?: { + [key: string]: string; + }; + name?: string; +}; + +export type HandlersMcpStdioResponse = { + session_id?: string; + tools?: Array; + url?: string; +}; + +export type HandlersSkillItem = { + content?: string; + description?: string; + metadata?: { + [key: string]: unknown; + }; + name?: string; +}; + +export type HandlersSkillsDeleteRequest = { + names?: Array; +}; + +export type HandlersSkillsResponse = { + skills?: Array; +}; + +export type HandlersSkillsUpsertRequest = { + skills?: Array; +}; + +export type HandlersSnapshotInfo = { + created_at?: string; + kind?: string; + labels?: { + [key: string]: string; + }; + name?: string; + parent?: string; + snapshotter?: string; + updated_at?: string; +}; + +export type HandlersMemoryAddPayload = { + embedding_enabled?: boolean; + filters?: { + [key: string]: unknown; + }; + infer?: boolean; + message?: string; + messages?: Array; + metadata?: { + [key: string]: unknown; + }; + run_id?: string; +}; + +export type HandlersMemoryDeleteAllPayload = { + run_id?: string; +}; + +export type HandlersMemoryEmbedUpsertPayload = { + filters?: { + [key: string]: unknown; + }; + input?: MemoryEmbedInput; + metadata?: { + [key: string]: unknown; + }; + model?: string; + provider?: string; + run_id?: string; + source?: string; + type?: string; +}; + +export type HandlersMemorySearchPayload = { + embedding_enabled?: boolean; + filters?: { + [key: string]: unknown; + }; + limit?: number; + query?: string; + run_id?: string; + sources?: Array; +}; + +export type HandlersSkillsOpResponse = { + ok?: boolean; +}; + +export type HistoryCreateRequest = { + messages?: Array<{ + [key: string]: unknown; + }>; + metadata?: { + [key: string]: unknown; + }; + skills?: Array; +}; + +export type HistoryListResponse = { + items?: Array; +}; + +export type HistoryRecord = { + bot_id?: string; + id?: string; + messages?: Array<{ + [key: string]: unknown; + }>; + metadata?: { + [key: string]: unknown; + }; + session_id?: string; + skills?: Array; + timestamp?: string; +}; + +export type McpListResponse = { + items?: Array; +}; + +export type McpUpsertRequest = { + active?: boolean; + config?: { + [key: string]: unknown; + }; + name?: string; + type?: string; +}; + +export type MemoryDeleteResponse = { + message?: string; +}; + +export type MemoryEmbedInput = { + image_url?: string; + text?: string; + video_url?: string; +}; + +export type MemoryEmbedUpsertResponse = { + dimensions?: number; + item?: MemoryMemoryItem; + model?: string; + provider?: string; +}; + +export type MemoryMemoryItem = { + agentId?: string; + botId?: string; + createdAt?: string; + hash?: string; + id?: string; + memory?: string; + metadata?: { + [key: string]: unknown; + }; + runId?: string; + score?: number; + sessionId?: string; + updatedAt?: string; +}; + +export type MemoryMessage = { + content?: string; + role?: string; +}; + +export type MemorySearchResponse = { + relations?: Array; + results?: Array; +}; + +export type MemoryUpdateRequest = { + embedding_enabled?: boolean; + memory?: string; + memory_id?: string; +}; + +export type ModelsAddRequest = { + dimensions?: number; + input?: Array; + is_multimodal?: boolean; + llm_provider_id: string; + model_id: string; + name: string; + type: ModelsModelType; +}; + +export type ModelsAddResponse = { + id?: string; + model_id?: string; +}; + +export type ModelsCountResponse = { + count?: number; +}; + +export type ModelsGetResponse = { + dimensions?: number; + input?: Array; + is_multimodal?: boolean; + llm_provider_id: string; + model_id: string; + name: string; + type: ModelsModelType; +}; + +export type ModelsModelType = 'chat' | 'embedding'; + +export type ModelsUpdateRequest = { + dimensions?: number; + input?: Array; + is_multimodal?: boolean; + llm_provider_id: string; + model_id: string; + name: string; + type: ModelsModelType; +}; + +export type ProvidersClientType = 'openai' | 'openai-compat' | 'anthropic' | 'google' | 'ollama'; + +export type ProvidersCountResponse = { + count?: number; +}; + +export type ProvidersCreateRequest = { + api_key?: string; + base_url: string; + client_type: ProvidersClientType; + metadata?: { + [key: string]: unknown; + }; + name: string; +}; + +export type ProvidersGetResponse = { + /** + * masked in response + */ + api_key?: string; + base_url: string; + client_type: string; + created_at: string; + id: string; + metadata?: { + [key: string]: unknown; + }; + name: string; + updated_at: string; +}; + +export type ProvidersUpdateRequest = { + api_key?: string; + base_url?: string; + client_type?: ProvidersClientType; + metadata?: { + [key: string]: unknown; + }; + name?: string; +}; + +export type ScheduleCreateRequest = { + command?: string; + description?: string; + enabled?: boolean; + max_calls?: ScheduleNullableInt; + name?: string; + pattern?: string; +}; + +export type ScheduleListResponse = { + items?: Array; +}; + +export type ScheduleNullableInt = { + set?: boolean; + value?: number; +}; + +export type ScheduleSchedule = { + bot_id?: string; + command?: string; + created_at?: string; + current_calls?: number; + description?: string; + enabled?: boolean; + id?: string; + max_calls?: number; + name?: string; + pattern?: string; + updated_at?: string; +}; + +export type ScheduleUpdateRequest = { + command?: string; + description?: string; + enabled?: boolean; + max_calls?: ScheduleNullableInt; + name?: string; + pattern?: string; +}; + +export type SettingsSettings = { + allow_guest: boolean; + chat_model_id: string; + embedding_model_id: string; + language: string; + max_context_load_time: number; + memory_model_id: string; +}; + +export type SettingsUpsertRequest = { + allow_guest?: boolean; + chat_model_id?: string; + embedding_model_id?: string; + language?: string; + max_context_load_time?: number; + memory_model_id?: string; +}; + +export type SubagentAddSkillsRequest = { + skills?: Array; +}; + +export type SubagentContextResponse = { + messages?: Array<{ + [key: string]: unknown; + }>; +}; + +export type SubagentCreateRequest = { + description?: string; + messages?: Array<{ + [key: string]: unknown; + }>; + metadata?: { + [key: string]: unknown; + }; + name?: string; + skills?: Array; +}; + +export type SubagentListResponse = { + items?: Array; +}; + +export type SubagentSkillsResponse = { + skills?: Array; +}; + +export type SubagentSubagent = { + bot_id?: string; + created_at?: string; + deleted?: boolean; + deleted_at?: string; + description?: string; + id?: string; + messages?: Array<{ + [key: string]: unknown; + }>; + metadata?: { + [key: string]: unknown; + }; + name?: string; + skills?: Array; + updated_at?: string; +}; + +export type SubagentUpdateContextRequest = { + messages?: Array<{ + [key: string]: unknown; + }>; +}; + +export type SubagentUpdateRequest = { + description?: string; + metadata?: { + [key: string]: unknown; + }; + name?: string; +}; + +export type SubagentUpdateSkillsRequest = { + skills?: Array; +}; + +export type UsersCreateUserRequest = { + avatar_url?: string; + display_name?: string; + email?: string; + is_active?: boolean; + password?: string; + role?: string; + username?: string; +}; + +export type UsersListUsersResponse = { + items?: Array; +}; + +export type UsersResetPasswordRequest = { + new_password?: string; +}; + +export type UsersUpdatePasswordRequest = { + current_password?: string; + new_password?: string; +}; + +export type UsersUpdateProfileRequest = { + avatar_url?: string; + display_name?: string; +}; + +export type UsersUpdateUserRequest = { + avatar_url?: string; + display_name?: string; + is_active?: boolean; + role?: string; +}; + +export type UsersUser = { + avatar_url?: string; + created_at?: string; + display_name?: string; + email?: string; + id?: string; + is_active?: boolean; + last_login_at?: string; + role?: string; + updated_at?: string; + username?: string; +}; + +export type PostAuthLoginData = { + /** + * Login request + */ + body: HandlersLoginRequest; + path?: never; + query?: never; + url: '/auth/login'; +}; + +export type PostAuthLoginErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Unauthorized + */ + 401: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostAuthLoginError = PostAuthLoginErrors[keyof PostAuthLoginErrors]; + +export type PostAuthLoginResponses = { + /** + * OK + */ + 200: HandlersLoginResponse; +}; + +export type PostAuthLoginResponse = PostAuthLoginResponses[keyof PostAuthLoginResponses]; + +export type GetBotsData = { + body?: never; + path?: never; + query?: { + /** + * Owner user ID (admin only) + */ + owner_id?: string; + }; + url: '/bots'; +}; + +export type GetBotsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsError = GetBotsErrors[keyof GetBotsErrors]; + +export type GetBotsResponses = { + /** + * OK + */ + 200: BotsListBotsResponse; +}; + +export type GetBotsResponse = GetBotsResponses[keyof GetBotsResponses]; + +export type PostBotsData = { + /** + * Bot payload + */ + body: BotsCreateBotRequest; + path?: never; + query?: never; + url: '/bots'; +}; + +export type PostBotsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsError = PostBotsErrors[keyof PostBotsErrors]; + +export type PostBotsResponses = { + /** + * Created + */ + 201: BotsBot; +}; + +export type PostBotsResponse = PostBotsResponses[keyof PostBotsResponses]; + +export type PostBotsByBotIdChatData = { + /** + * Chat request + */ + body: ChatChatRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/chat'; +}; + +export type PostBotsByBotIdChatErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdChatError = PostBotsByBotIdChatErrors[keyof PostBotsByBotIdChatErrors]; + +export type PostBotsByBotIdChatResponses = { + /** + * OK + */ + 200: ChatChatResponse; +}; + +export type PostBotsByBotIdChatResponse = PostBotsByBotIdChatResponses[keyof PostBotsByBotIdChatResponses]; + +export type PostBotsByBotIdChatStreamData = { + /** + * Chat request + */ + body: ChatChatRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/chat/stream'; +}; + +export type PostBotsByBotIdChatStreamErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdChatStreamError = PostBotsByBotIdChatStreamErrors[keyof PostBotsByBotIdChatStreamErrors]; + +export type PostBotsByBotIdChatStreamResponses = { + /** + * OK + */ + 200: string; +}; + +export type PostBotsByBotIdChatStreamResponse = PostBotsByBotIdChatStreamResponses[keyof PostBotsByBotIdChatStreamResponses]; + +export type DeleteBotsByBotIdContainerData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container'; +}; + +export type DeleteBotsByBotIdContainerErrors = { + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdContainerError = DeleteBotsByBotIdContainerErrors[keyof DeleteBotsByBotIdContainerErrors]; + +export type DeleteBotsByBotIdContainerResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdContainerData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container'; +}; + +export type GetBotsByBotIdContainerErrors = { + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerError = GetBotsByBotIdContainerErrors[keyof GetBotsByBotIdContainerErrors]; + +export type GetBotsByBotIdContainerResponses = { + /** + * OK + */ + 200: HandlersGetContainerResponse; +}; + +export type GetBotsByBotIdContainerResponse = GetBotsByBotIdContainerResponses[keyof GetBotsByBotIdContainerResponses]; + +export type PostBotsByBotIdContainerData = { + /** + * Create container payload + */ + body: HandlersCreateContainerRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container'; +}; + +export type PostBotsByBotIdContainerErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerError = PostBotsByBotIdContainerErrors[keyof PostBotsByBotIdContainerErrors]; + +export type PostBotsByBotIdContainerResponses = { + /** + * OK + */ + 200: HandlersCreateContainerResponse; +}; + +export type PostBotsByBotIdContainerResponse = PostBotsByBotIdContainerResponses[keyof PostBotsByBotIdContainerResponses]; + +export type DeleteBotsByBotIdContainerFsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query: { + /** + * Relative path + */ + path: string; + /** + * Recursive delete for directories + */ + recursive?: boolean; + }; + url: '/bots/{bot_id}/container/fs'; +}; + +export type DeleteBotsByBotIdContainerFsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdContainerFsError = DeleteBotsByBotIdContainerFsErrors[keyof DeleteBotsByBotIdContainerFsErrors]; + +export type DeleteBotsByBotIdContainerFsResponses = { + /** + * OK + */ + 200: HandlersFsDeleteResponse; +}; + +export type DeleteBotsByBotIdContainerFsResponse = DeleteBotsByBotIdContainerFsResponses[keyof DeleteBotsByBotIdContainerFsResponses]; + +export type GetBotsByBotIdContainerFsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Relative directory path + */ + path?: string; + /** + * Recursive listing + */ + recursive?: boolean; + }; + url: '/bots/{bot_id}/container/fs'; +}; + +export type GetBotsByBotIdContainerFsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerFsError = GetBotsByBotIdContainerFsErrors[keyof GetBotsByBotIdContainerFsErrors]; + +export type GetBotsByBotIdContainerFsResponses = { + /** + * OK + */ + 200: HandlersFsListResponse; +}; + +export type GetBotsByBotIdContainerFsResponse = GetBotsByBotIdContainerFsResponses[keyof GetBotsByBotIdContainerFsResponses]; + +export type PostBotsByBotIdContainerFsMcpData = { + /** + * JSON-RPC request + */ + body: { + [key: string]: unknown; + }; + headers: { + /** + * Bearer + */ + Authorization: string; + }; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/fs-mcp'; +}; + +export type PostBotsByBotIdContainerFsMcpErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerFsMcpError = PostBotsByBotIdContainerFsMcpErrors[keyof PostBotsByBotIdContainerFsMcpErrors]; + +export type PostBotsByBotIdContainerFsMcpResponses = { + /** + * JSON-RPC response: {jsonrpc,id,result|error} + */ + 200: { + [key: string]: unknown; + }; +}; + +export type PostBotsByBotIdContainerFsMcpResponse = PostBotsByBotIdContainerFsMcpResponses[keyof PostBotsByBotIdContainerFsMcpResponses]; + +export type PostBotsByBotIdContainerFsDirData = { + /** + * Directory payload + */ + body: HandlersFsMkdirRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/fs/dir'; +}; + +export type PostBotsByBotIdContainerFsDirErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerFsDirError = PostBotsByBotIdContainerFsDirErrors[keyof PostBotsByBotIdContainerFsDirErrors]; + +export type PostBotsByBotIdContainerFsDirResponses = { + /** + * OK + */ + 200: HandlersFsWriteResponse; +}; + +export type PostBotsByBotIdContainerFsDirResponse = PostBotsByBotIdContainerFsDirResponses[keyof PostBotsByBotIdContainerFsDirResponses]; + +export type GetBotsByBotIdContainerFsFileData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query: { + /** + * Relative file path + */ + path: string; + }; + url: '/bots/{bot_id}/container/fs/file'; +}; + +export type GetBotsByBotIdContainerFsFileErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerFsFileError = GetBotsByBotIdContainerFsFileErrors[keyof GetBotsByBotIdContainerFsFileErrors]; + +export type GetBotsByBotIdContainerFsFileResponses = { + /** + * OK + */ + 200: HandlersFsReadResponse; +}; + +export type GetBotsByBotIdContainerFsFileResponse = GetBotsByBotIdContainerFsFileResponses[keyof GetBotsByBotIdContainerFsFileResponses]; + +export type PostBotsByBotIdContainerFsFileData = { + /** + * File write payload + */ + body: HandlersFsWriteRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/fs/file'; +}; + +export type PostBotsByBotIdContainerFsFileErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Conflict + */ + 409: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerFsFileError = PostBotsByBotIdContainerFsFileErrors[keyof PostBotsByBotIdContainerFsFileErrors]; + +export type PostBotsByBotIdContainerFsFileResponses = { + /** + * OK + */ + 200: HandlersFsWriteResponse; +}; + +export type PostBotsByBotIdContainerFsFileResponse = PostBotsByBotIdContainerFsFileResponses[keyof PostBotsByBotIdContainerFsFileResponses]; + +export type GetBotsByBotIdContainerFsStatData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query: { + /** + * Relative path + */ + path: string; + }; + url: '/bots/{bot_id}/container/fs/stat'; +}; + +export type GetBotsByBotIdContainerFsStatErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerFsStatError = GetBotsByBotIdContainerFsStatErrors[keyof GetBotsByBotIdContainerFsStatErrors]; + +export type GetBotsByBotIdContainerFsStatResponses = { + /** + * OK + */ + 200: HandlersFsStatResponse; +}; + +export type GetBotsByBotIdContainerFsStatResponse = GetBotsByBotIdContainerFsStatResponses[keyof GetBotsByBotIdContainerFsStatResponses]; + +export type PostBotsByBotIdContainerFsUploadData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Relative file path or directory + */ + path?: string; + }; + url: '/bots/{bot_id}/container/fs/upload'; +}; + +export type PostBotsByBotIdContainerFsUploadErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerFsUploadError = PostBotsByBotIdContainerFsUploadErrors[keyof PostBotsByBotIdContainerFsUploadErrors]; + +export type PostBotsByBotIdContainerFsUploadResponses = { + /** + * OK + */ + 200: HandlersFsWriteResponse; +}; + +export type PostBotsByBotIdContainerFsUploadResponse = PostBotsByBotIdContainerFsUploadResponses[keyof PostBotsByBotIdContainerFsUploadResponses]; + +export type GetBotsByBotIdContainerFsUsageData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Relative directory path + */ + path?: string; + }; + url: '/bots/{bot_id}/container/fs/usage'; +}; + +export type GetBotsByBotIdContainerFsUsageErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerFsUsageError = GetBotsByBotIdContainerFsUsageErrors[keyof GetBotsByBotIdContainerFsUsageErrors]; + +export type GetBotsByBotIdContainerFsUsageResponses = { + /** + * OK + */ + 200: HandlersFsUsageResponse; +}; + +export type GetBotsByBotIdContainerFsUsageResponse = GetBotsByBotIdContainerFsUsageResponses[keyof GetBotsByBotIdContainerFsUsageResponses]; + +export type DeleteBotsByBotIdContainerSkillsData = { + /** + * Delete skills payload + */ + body: HandlersSkillsDeleteRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/skills'; +}; + +export type DeleteBotsByBotIdContainerSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdContainerSkillsError = DeleteBotsByBotIdContainerSkillsErrors[keyof DeleteBotsByBotIdContainerSkillsErrors]; + +export type DeleteBotsByBotIdContainerSkillsResponses = { + /** + * OK + */ + 200: HandlersSkillsOpResponse; +}; + +export type DeleteBotsByBotIdContainerSkillsResponse = DeleteBotsByBotIdContainerSkillsResponses[keyof DeleteBotsByBotIdContainerSkillsResponses]; + +export type GetBotsByBotIdContainerSkillsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/skills'; +}; + +export type GetBotsByBotIdContainerSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdContainerSkillsError = GetBotsByBotIdContainerSkillsErrors[keyof GetBotsByBotIdContainerSkillsErrors]; + +export type GetBotsByBotIdContainerSkillsResponses = { + /** + * OK + */ + 200: HandlersSkillsResponse; +}; + +export type GetBotsByBotIdContainerSkillsResponse = GetBotsByBotIdContainerSkillsResponses[keyof GetBotsByBotIdContainerSkillsResponses]; + +export type PostBotsByBotIdContainerSkillsData = { + /** + * Skills payload + */ + body: HandlersSkillsUpsertRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/skills'; +}; + +export type PostBotsByBotIdContainerSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerSkillsError = PostBotsByBotIdContainerSkillsErrors[keyof PostBotsByBotIdContainerSkillsErrors]; + +export type PostBotsByBotIdContainerSkillsResponses = { + /** + * OK + */ + 200: HandlersSkillsOpResponse; +}; + +export type PostBotsByBotIdContainerSkillsResponse = PostBotsByBotIdContainerSkillsResponses[keyof PostBotsByBotIdContainerSkillsResponses]; + +export type GetBotsByBotIdContainerSnapshotsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Snapshotter name + */ + snapshotter?: string; + }; + url: '/bots/{bot_id}/container/snapshots'; +}; + +export type GetBotsByBotIdContainerSnapshotsResponses = { + /** + * OK + */ + 200: HandlersListSnapshotsResponse; +}; + +export type GetBotsByBotIdContainerSnapshotsResponse = GetBotsByBotIdContainerSnapshotsResponses[keyof GetBotsByBotIdContainerSnapshotsResponses]; + +export type PostBotsByBotIdContainerSnapshotsData = { + /** + * Create snapshot payload + */ + body: HandlersCreateSnapshotRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/snapshots'; +}; + +export type PostBotsByBotIdContainerSnapshotsErrors = { + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerSnapshotsError = PostBotsByBotIdContainerSnapshotsErrors[keyof PostBotsByBotIdContainerSnapshotsErrors]; + +export type PostBotsByBotIdContainerSnapshotsResponses = { + /** + * OK + */ + 200: HandlersCreateSnapshotResponse; +}; + +export type PostBotsByBotIdContainerSnapshotsResponse = PostBotsByBotIdContainerSnapshotsResponses[keyof PostBotsByBotIdContainerSnapshotsResponses]; + +export type PostBotsByBotIdContainerStartData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/start'; +}; + +export type PostBotsByBotIdContainerStartErrors = { + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerStartError = PostBotsByBotIdContainerStartErrors[keyof PostBotsByBotIdContainerStartErrors]; + +export type PostBotsByBotIdContainerStartResponses = { + /** + * OK + */ + 200: { + [key: string]: unknown; + }; +}; + +export type PostBotsByBotIdContainerStartResponse = PostBotsByBotIdContainerStartResponses[keyof PostBotsByBotIdContainerStartResponses]; + +export type PostBotsByBotIdContainerStopData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/container/stop'; +}; + +export type PostBotsByBotIdContainerStopErrors = { + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdContainerStopError = PostBotsByBotIdContainerStopErrors[keyof PostBotsByBotIdContainerStopErrors]; + +export type PostBotsByBotIdContainerStopResponses = { + /** + * OK + */ + 200: { + [key: string]: unknown; + }; +}; + +export type PostBotsByBotIdContainerStopResponse = PostBotsByBotIdContainerStopResponses[keyof PostBotsByBotIdContainerStopResponses]; + +export type DeleteBotsByBotIdHistoryData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/history'; +}; + +export type DeleteBotsByBotIdHistoryErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdHistoryError = DeleteBotsByBotIdHistoryErrors[keyof DeleteBotsByBotIdHistoryErrors]; + +export type DeleteBotsByBotIdHistoryResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdHistoryData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Limit + */ + limit?: number; + }; + url: '/bots/{bot_id}/history'; +}; + +export type GetBotsByBotIdHistoryErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdHistoryError = GetBotsByBotIdHistoryErrors[keyof GetBotsByBotIdHistoryErrors]; + +export type GetBotsByBotIdHistoryResponses = { + /** + * OK + */ + 200: HistoryListResponse; +}; + +export type GetBotsByBotIdHistoryResponse = GetBotsByBotIdHistoryResponses[keyof GetBotsByBotIdHistoryResponses]; + +export type PostBotsByBotIdHistoryData = { + /** + * History payload + */ + body: HistoryCreateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/history'; +}; + +export type PostBotsByBotIdHistoryErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdHistoryError = PostBotsByBotIdHistoryErrors[keyof PostBotsByBotIdHistoryErrors]; + +export type PostBotsByBotIdHistoryResponses = { + /** + * Created + */ + 201: HistoryRecord; +}; + +export type PostBotsByBotIdHistoryResponse = PostBotsByBotIdHistoryResponses[keyof PostBotsByBotIdHistoryResponses]; + +export type DeleteBotsByBotIdHistoryByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * History ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/history/{id}'; +}; + +export type DeleteBotsByBotIdHistoryByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdHistoryByIdError = DeleteBotsByBotIdHistoryByIdErrors[keyof DeleteBotsByBotIdHistoryByIdErrors]; + +export type DeleteBotsByBotIdHistoryByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdHistoryByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * History ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/history/{id}'; +}; + +export type GetBotsByBotIdHistoryByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdHistoryByIdError = GetBotsByBotIdHistoryByIdErrors[keyof GetBotsByBotIdHistoryByIdErrors]; + +export type GetBotsByBotIdHistoryByIdResponses = { + /** + * OK + */ + 200: HistoryRecord; +}; + +export type GetBotsByBotIdHistoryByIdResponse = GetBotsByBotIdHistoryByIdResponses[keyof GetBotsByBotIdHistoryByIdResponses]; + +export type GetBotsByBotIdMcpData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp'; +}; + +export type GetBotsByBotIdMcpErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdMcpError = GetBotsByBotIdMcpErrors[keyof GetBotsByBotIdMcpErrors]; + +export type GetBotsByBotIdMcpResponses = { + /** + * OK + */ + 200: McpListResponse; +}; + +export type GetBotsByBotIdMcpResponse = GetBotsByBotIdMcpResponses[keyof GetBotsByBotIdMcpResponses]; + +export type PostBotsByBotIdMcpData = { + /** + * MCP payload + */ + body: McpUpsertRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp'; +}; + +export type PostBotsByBotIdMcpErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMcpError = PostBotsByBotIdMcpErrors[keyof PostBotsByBotIdMcpErrors]; + +export type PostBotsByBotIdMcpResponses = { + /** + * Created + */ + 201: GithubComMemohaiMemohInternalMcpConnection; +}; + +export type PostBotsByBotIdMcpResponse = PostBotsByBotIdMcpResponses[keyof PostBotsByBotIdMcpResponses]; + +export type PostBotsByBotIdMcpStdioData = { + /** + * Stdio MCP payload + */ + body: HandlersMcpStdioRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp-stdio'; +}; + +export type PostBotsByBotIdMcpStdioErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMcpStdioError = PostBotsByBotIdMcpStdioErrors[keyof PostBotsByBotIdMcpStdioErrors]; + +export type PostBotsByBotIdMcpStdioResponses = { + /** + * OK + */ + 200: HandlersMcpStdioResponse; +}; + +export type PostBotsByBotIdMcpStdioResponse = PostBotsByBotIdMcpStdioResponses[keyof PostBotsByBotIdMcpStdioResponses]; + +export type PostBotsByBotIdMcpStdioBySessionIdData = { + /** + * JSON-RPC request + */ + body: { + [key: string]: unknown; + }; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Session ID + */ + session_id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp-stdio/{session_id}'; +}; + +export type PostBotsByBotIdMcpStdioBySessionIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMcpStdioBySessionIdError = PostBotsByBotIdMcpStdioBySessionIdErrors[keyof PostBotsByBotIdMcpStdioBySessionIdErrors]; + +export type PostBotsByBotIdMcpStdioBySessionIdResponses = { + /** + * JSON-RPC response: {jsonrpc,id,result|error} + */ + 200: { + [key: string]: unknown; + }; +}; + +export type PostBotsByBotIdMcpStdioBySessionIdResponse = PostBotsByBotIdMcpStdioBySessionIdResponses[keyof PostBotsByBotIdMcpStdioBySessionIdResponses]; + +export type DeleteBotsByBotIdMcpByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * MCP ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp/{id}'; +}; + +export type DeleteBotsByBotIdMcpByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdMcpByIdError = DeleteBotsByBotIdMcpByIdErrors[keyof DeleteBotsByBotIdMcpByIdErrors]; + +export type DeleteBotsByBotIdMcpByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdMcpByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * MCP ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp/{id}'; +}; + +export type GetBotsByBotIdMcpByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdMcpByIdError = GetBotsByBotIdMcpByIdErrors[keyof GetBotsByBotIdMcpByIdErrors]; + +export type GetBotsByBotIdMcpByIdResponses = { + /** + * OK + */ + 200: GithubComMemohaiMemohInternalMcpConnection; +}; + +export type GetBotsByBotIdMcpByIdResponse = GetBotsByBotIdMcpByIdResponses[keyof GetBotsByBotIdMcpByIdResponses]; + +export type PutBotsByBotIdMcpByIdData = { + /** + * MCP payload + */ + body: McpUpsertRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * MCP ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/mcp/{id}'; +}; + +export type PutBotsByBotIdMcpByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdMcpByIdError = PutBotsByBotIdMcpByIdErrors[keyof PutBotsByBotIdMcpByIdErrors]; + +export type PutBotsByBotIdMcpByIdResponses = { + /** + * OK + */ + 200: GithubComMemohaiMemohInternalMcpConnection; +}; + +export type PutBotsByBotIdMcpByIdResponse = PutBotsByBotIdMcpByIdResponses[keyof PutBotsByBotIdMcpByIdResponses]; + +export type PostBotsByBotIdMemoryAddData = { + /** + * Add request + */ + body: HandlersMemoryAddPayload; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/add'; +}; + +export type PostBotsByBotIdMemoryAddErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMemoryAddError = PostBotsByBotIdMemoryAddErrors[keyof PostBotsByBotIdMemoryAddErrors]; + +export type PostBotsByBotIdMemoryAddResponses = { + /** + * OK + */ + 200: MemorySearchResponse; +}; + +export type PostBotsByBotIdMemoryAddResponse = PostBotsByBotIdMemoryAddResponses[keyof PostBotsByBotIdMemoryAddResponses]; + +export type PostBotsByBotIdMemoryEmbedData = { + /** + * Embed upsert request + */ + body: HandlersMemoryEmbedUpsertPayload; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/embed'; +}; + +export type PostBotsByBotIdMemoryEmbedErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMemoryEmbedError = PostBotsByBotIdMemoryEmbedErrors[keyof PostBotsByBotIdMemoryEmbedErrors]; + +export type PostBotsByBotIdMemoryEmbedResponses = { + /** + * OK + */ + 200: MemoryEmbedUpsertResponse; +}; + +export type PostBotsByBotIdMemoryEmbedResponse = PostBotsByBotIdMemoryEmbedResponses[keyof PostBotsByBotIdMemoryEmbedResponses]; + +export type DeleteBotsByBotIdMemoryMemoriesData = { + /** + * Delete all request + */ + body: HandlersMemoryDeleteAllPayload; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/memories'; +}; + +export type DeleteBotsByBotIdMemoryMemoriesErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdMemoryMemoriesError = DeleteBotsByBotIdMemoryMemoriesErrors[keyof DeleteBotsByBotIdMemoryMemoriesErrors]; + +export type DeleteBotsByBotIdMemoryMemoriesResponses = { + /** + * OK + */ + 200: MemoryDeleteResponse; +}; + +export type DeleteBotsByBotIdMemoryMemoriesResponse = DeleteBotsByBotIdMemoryMemoriesResponses[keyof DeleteBotsByBotIdMemoryMemoriesResponses]; + +export type GetBotsByBotIdMemoryMemoriesData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: { + /** + * Run ID + */ + run_id?: string; + /** + * Limit + */ + limit?: number; + }; + url: '/bots/{bot_id}/memory/memories'; +}; + +export type GetBotsByBotIdMemoryMemoriesErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdMemoryMemoriesError = GetBotsByBotIdMemoryMemoriesErrors[keyof GetBotsByBotIdMemoryMemoriesErrors]; + +export type GetBotsByBotIdMemoryMemoriesResponses = { + /** + * OK + */ + 200: MemorySearchResponse; +}; + +export type GetBotsByBotIdMemoryMemoriesResponse = GetBotsByBotIdMemoryMemoriesResponses[keyof GetBotsByBotIdMemoryMemoriesResponses]; + +export type DeleteBotsByBotIdMemoryMemoriesByMemoryIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Memory ID + */ + memoryId: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/memories/{memoryId}'; +}; + +export type DeleteBotsByBotIdMemoryMemoriesByMemoryIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdMemoryMemoriesByMemoryIdError = DeleteBotsByBotIdMemoryMemoriesByMemoryIdErrors[keyof DeleteBotsByBotIdMemoryMemoriesByMemoryIdErrors]; + +export type DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponses = { + /** + * OK + */ + 200: MemoryDeleteResponse; +}; + +export type DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponse = DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponses[keyof DeleteBotsByBotIdMemoryMemoriesByMemoryIdResponses]; + +export type GetBotsByBotIdMemoryMemoriesByMemoryIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Memory ID + */ + memoryId: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/memories/{memoryId}'; +}; + +export type GetBotsByBotIdMemoryMemoriesByMemoryIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdMemoryMemoriesByMemoryIdError = GetBotsByBotIdMemoryMemoriesByMemoryIdErrors[keyof GetBotsByBotIdMemoryMemoriesByMemoryIdErrors]; + +export type GetBotsByBotIdMemoryMemoriesByMemoryIdResponses = { + /** + * OK + */ + 200: MemoryMemoryItem; +}; + +export type GetBotsByBotIdMemoryMemoriesByMemoryIdResponse = GetBotsByBotIdMemoryMemoriesByMemoryIdResponses[keyof GetBotsByBotIdMemoryMemoriesByMemoryIdResponses]; + +export type PostBotsByBotIdMemorySearchData = { + /** + * Search request + */ + body: HandlersMemorySearchPayload; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/search'; +}; + +export type PostBotsByBotIdMemorySearchErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMemorySearchError = PostBotsByBotIdMemorySearchErrors[keyof PostBotsByBotIdMemorySearchErrors]; + +export type PostBotsByBotIdMemorySearchResponses = { + /** + * OK + */ + 200: MemorySearchResponse; +}; + +export type PostBotsByBotIdMemorySearchResponse = PostBotsByBotIdMemorySearchResponses[keyof PostBotsByBotIdMemorySearchResponses]; + +export type PostBotsByBotIdMemoryUpdateData = { + /** + * Update request + */ + body: MemoryUpdateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/memory/update'; +}; + +export type PostBotsByBotIdMemoryUpdateErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdMemoryUpdateError = PostBotsByBotIdMemoryUpdateErrors[keyof PostBotsByBotIdMemoryUpdateErrors]; + +export type PostBotsByBotIdMemoryUpdateResponses = { + /** + * OK + */ + 200: MemoryMemoryItem; +}; + +export type PostBotsByBotIdMemoryUpdateResponse = PostBotsByBotIdMemoryUpdateResponses[keyof PostBotsByBotIdMemoryUpdateResponses]; + +export type GetBotsByBotIdScheduleData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/schedule'; +}; + +export type GetBotsByBotIdScheduleErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdScheduleError = GetBotsByBotIdScheduleErrors[keyof GetBotsByBotIdScheduleErrors]; + +export type GetBotsByBotIdScheduleResponses = { + /** + * OK + */ + 200: ScheduleListResponse; +}; + +export type GetBotsByBotIdScheduleResponse = GetBotsByBotIdScheduleResponses[keyof GetBotsByBotIdScheduleResponses]; + +export type PostBotsByBotIdScheduleData = { + /** + * Schedule payload + */ + body: ScheduleCreateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/schedule'; +}; + +export type PostBotsByBotIdScheduleErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdScheduleError = PostBotsByBotIdScheduleErrors[keyof PostBotsByBotIdScheduleErrors]; + +export type PostBotsByBotIdScheduleResponses = { + /** + * Created + */ + 201: ScheduleSchedule; +}; + +export type PostBotsByBotIdScheduleResponse = PostBotsByBotIdScheduleResponses[keyof PostBotsByBotIdScheduleResponses]; + +export type DeleteBotsByBotIdScheduleByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Schedule ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/schedule/{id}'; +}; + +export type DeleteBotsByBotIdScheduleByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdScheduleByIdError = DeleteBotsByBotIdScheduleByIdErrors[keyof DeleteBotsByBotIdScheduleByIdErrors]; + +export type DeleteBotsByBotIdScheduleByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdScheduleByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Schedule ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/schedule/{id}'; +}; + +export type GetBotsByBotIdScheduleByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdScheduleByIdError = GetBotsByBotIdScheduleByIdErrors[keyof GetBotsByBotIdScheduleByIdErrors]; + +export type GetBotsByBotIdScheduleByIdResponses = { + /** + * OK + */ + 200: ScheduleSchedule; +}; + +export type GetBotsByBotIdScheduleByIdResponse = GetBotsByBotIdScheduleByIdResponses[keyof GetBotsByBotIdScheduleByIdResponses]; + +export type PutBotsByBotIdScheduleByIdData = { + /** + * Schedule payload + */ + body: ScheduleUpdateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Schedule ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/schedule/{id}'; +}; + +export type PutBotsByBotIdScheduleByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdScheduleByIdError = PutBotsByBotIdScheduleByIdErrors[keyof PutBotsByBotIdScheduleByIdErrors]; + +export type PutBotsByBotIdScheduleByIdResponses = { + /** + * OK + */ + 200: ScheduleSchedule; +}; + +export type PutBotsByBotIdScheduleByIdResponse = PutBotsByBotIdScheduleByIdResponses[keyof PutBotsByBotIdScheduleByIdResponses]; + +export type DeleteBotsByBotIdSettingsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/settings'; +}; + +export type DeleteBotsByBotIdSettingsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdSettingsError = DeleteBotsByBotIdSettingsErrors[keyof DeleteBotsByBotIdSettingsErrors]; + +export type DeleteBotsByBotIdSettingsResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdSettingsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/settings'; +}; + +export type GetBotsByBotIdSettingsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdSettingsError = GetBotsByBotIdSettingsErrors[keyof GetBotsByBotIdSettingsErrors]; + +export type GetBotsByBotIdSettingsResponses = { + /** + * OK + */ + 200: SettingsSettings; +}; + +export type GetBotsByBotIdSettingsResponse = GetBotsByBotIdSettingsResponses[keyof GetBotsByBotIdSettingsResponses]; + +export type PostBotsByBotIdSettingsData = { + /** + * Settings payload + */ + body: SettingsUpsertRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/settings'; +}; + +export type PostBotsByBotIdSettingsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdSettingsError = PostBotsByBotIdSettingsErrors[keyof PostBotsByBotIdSettingsErrors]; + +export type PostBotsByBotIdSettingsResponses = { + /** + * OK + */ + 200: SettingsSettings; +}; + +export type PostBotsByBotIdSettingsResponse = PostBotsByBotIdSettingsResponses[keyof PostBotsByBotIdSettingsResponses]; + +export type PutBotsByBotIdSettingsData = { + /** + * Settings payload + */ + body: SettingsUpsertRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/settings'; +}; + +export type PutBotsByBotIdSettingsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdSettingsError = PutBotsByBotIdSettingsErrors[keyof PutBotsByBotIdSettingsErrors]; + +export type PutBotsByBotIdSettingsResponses = { + /** + * OK + */ + 200: SettingsSettings; +}; + +export type PutBotsByBotIdSettingsResponse = PutBotsByBotIdSettingsResponses[keyof PutBotsByBotIdSettingsResponses]; + +export type GetBotsByBotIdSubagentsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents'; +}; + +export type GetBotsByBotIdSubagentsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdSubagentsError = GetBotsByBotIdSubagentsErrors[keyof GetBotsByBotIdSubagentsErrors]; + +export type GetBotsByBotIdSubagentsResponses = { + /** + * OK + */ + 200: SubagentListResponse; +}; + +export type GetBotsByBotIdSubagentsResponse = GetBotsByBotIdSubagentsResponses[keyof GetBotsByBotIdSubagentsResponses]; + +export type PostBotsByBotIdSubagentsData = { + /** + * Subagent payload + */ + body: SubagentCreateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents'; +}; + +export type PostBotsByBotIdSubagentsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdSubagentsError = PostBotsByBotIdSubagentsErrors[keyof PostBotsByBotIdSubagentsErrors]; + +export type PostBotsByBotIdSubagentsResponses = { + /** + * Created + */ + 201: SubagentSubagent; +}; + +export type PostBotsByBotIdSubagentsResponse = PostBotsByBotIdSubagentsResponses[keyof PostBotsByBotIdSubagentsResponses]; + +export type DeleteBotsByBotIdSubagentsByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}'; +}; + +export type DeleteBotsByBotIdSubagentsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByBotIdSubagentsByIdError = DeleteBotsByBotIdSubagentsByIdErrors[keyof DeleteBotsByBotIdSubagentsByIdErrors]; + +export type DeleteBotsByBotIdSubagentsByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByBotIdSubagentsByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}'; +}; + +export type GetBotsByBotIdSubagentsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdSubagentsByIdError = GetBotsByBotIdSubagentsByIdErrors[keyof GetBotsByBotIdSubagentsByIdErrors]; + +export type GetBotsByBotIdSubagentsByIdResponses = { + /** + * OK + */ + 200: SubagentSubagent; +}; + +export type GetBotsByBotIdSubagentsByIdResponse = GetBotsByBotIdSubagentsByIdResponses[keyof GetBotsByBotIdSubagentsByIdResponses]; + +export type PutBotsByBotIdSubagentsByIdData = { + /** + * Subagent payload + */ + body: SubagentUpdateRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}'; +}; + +export type PutBotsByBotIdSubagentsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdSubagentsByIdError = PutBotsByBotIdSubagentsByIdErrors[keyof PutBotsByBotIdSubagentsByIdErrors]; + +export type PutBotsByBotIdSubagentsByIdResponses = { + /** + * OK + */ + 200: SubagentSubagent; +}; + +export type PutBotsByBotIdSubagentsByIdResponse = PutBotsByBotIdSubagentsByIdResponses[keyof PutBotsByBotIdSubagentsByIdResponses]; + +export type GetBotsByBotIdSubagentsByIdContextData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}/context'; +}; + +export type GetBotsByBotIdSubagentsByIdContextErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdSubagentsByIdContextError = GetBotsByBotIdSubagentsByIdContextErrors[keyof GetBotsByBotIdSubagentsByIdContextErrors]; + +export type GetBotsByBotIdSubagentsByIdContextResponses = { + /** + * OK + */ + 200: SubagentContextResponse; +}; + +export type GetBotsByBotIdSubagentsByIdContextResponse = GetBotsByBotIdSubagentsByIdContextResponses[keyof GetBotsByBotIdSubagentsByIdContextResponses]; + +export type PutBotsByBotIdSubagentsByIdContextData = { + /** + * Context payload + */ + body: SubagentUpdateContextRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}/context'; +}; + +export type PutBotsByBotIdSubagentsByIdContextErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdSubagentsByIdContextError = PutBotsByBotIdSubagentsByIdContextErrors[keyof PutBotsByBotIdSubagentsByIdContextErrors]; + +export type PutBotsByBotIdSubagentsByIdContextResponses = { + /** + * OK + */ + 200: SubagentContextResponse; +}; + +export type PutBotsByBotIdSubagentsByIdContextResponse = PutBotsByBotIdSubagentsByIdContextResponses[keyof PutBotsByBotIdSubagentsByIdContextResponses]; + +export type GetBotsByBotIdSubagentsByIdSkillsData = { + body?: never; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}/skills'; +}; + +export type GetBotsByBotIdSubagentsByIdSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByBotIdSubagentsByIdSkillsError = GetBotsByBotIdSubagentsByIdSkillsErrors[keyof GetBotsByBotIdSubagentsByIdSkillsErrors]; + +export type GetBotsByBotIdSubagentsByIdSkillsResponses = { + /** + * OK + */ + 200: SubagentSkillsResponse; +}; + +export type GetBotsByBotIdSubagentsByIdSkillsResponse = GetBotsByBotIdSubagentsByIdSkillsResponses[keyof GetBotsByBotIdSubagentsByIdSkillsResponses]; + +export type PostBotsByBotIdSubagentsByIdSkillsData = { + /** + * Skills payload + */ + body: SubagentAddSkillsRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}/skills'; +}; + +export type PostBotsByBotIdSubagentsByIdSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByBotIdSubagentsByIdSkillsError = PostBotsByBotIdSubagentsByIdSkillsErrors[keyof PostBotsByBotIdSubagentsByIdSkillsErrors]; + +export type PostBotsByBotIdSubagentsByIdSkillsResponses = { + /** + * OK + */ + 200: SubagentSkillsResponse; +}; + +export type PostBotsByBotIdSubagentsByIdSkillsResponse = PostBotsByBotIdSubagentsByIdSkillsResponses[keyof PostBotsByBotIdSubagentsByIdSkillsResponses]; + +export type PutBotsByBotIdSubagentsByIdSkillsData = { + /** + * Skills payload + */ + body: SubagentUpdateSkillsRequest; + path: { + /** + * Bot ID + */ + bot_id: string; + /** + * Subagent ID + */ + id: string; + }; + query?: never; + url: '/bots/{bot_id}/subagents/{id}/skills'; +}; + +export type PutBotsByBotIdSubagentsByIdSkillsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByBotIdSubagentsByIdSkillsError = PutBotsByBotIdSubagentsByIdSkillsErrors[keyof PutBotsByBotIdSubagentsByIdSkillsErrors]; + +export type PutBotsByBotIdSubagentsByIdSkillsResponses = { + /** + * OK + */ + 200: SubagentSkillsResponse; +}; + +export type PutBotsByBotIdSubagentsByIdSkillsResponse = PutBotsByBotIdSubagentsByIdSkillsResponses[keyof PutBotsByBotIdSubagentsByIdSkillsResponses]; + +export type DeleteBotsByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}'; +}; + +export type DeleteBotsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByIdError = DeleteBotsByIdErrors[keyof DeleteBotsByIdErrors]; + +export type DeleteBotsByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetBotsByIdData = { + body?: never; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}'; +}; + +export type GetBotsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByIdError = GetBotsByIdErrors[keyof GetBotsByIdErrors]; + +export type GetBotsByIdResponses = { + /** + * OK + */ + 200: BotsBot; +}; + +export type GetBotsByIdResponse = GetBotsByIdResponses[keyof GetBotsByIdResponses]; + +export type PutBotsByIdData = { + /** + * Bot update payload + */ + body: BotsUpdateBotRequest; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}'; +}; + +export type PutBotsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByIdError = PutBotsByIdErrors[keyof PutBotsByIdErrors]; + +export type PutBotsByIdResponses = { + /** + * OK + */ + 200: BotsBot; +}; + +export type PutBotsByIdResponse = PutBotsByIdResponses[keyof PutBotsByIdResponses]; + +export type GetBotsByIdChannelByPlatformData = { + body?: never; + path: { + /** + * Bot ID + */ + id: string; + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/bots/{id}/channel/{platform}'; +}; + +export type GetBotsByIdChannelByPlatformErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByIdChannelByPlatformError = GetBotsByIdChannelByPlatformErrors[keyof GetBotsByIdChannelByPlatformErrors]; + +export type GetBotsByIdChannelByPlatformResponses = { + /** + * OK + */ + 200: ChannelChannelConfig; +}; + +export type GetBotsByIdChannelByPlatformResponse = GetBotsByIdChannelByPlatformResponses[keyof GetBotsByIdChannelByPlatformResponses]; + +export type PutBotsByIdChannelByPlatformData = { + /** + * Channel config payload + */ + body: ChannelUpsertConfigRequest; + path: { + /** + * Bot ID + */ + id: string; + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/bots/{id}/channel/{platform}'; +}; + +export type PutBotsByIdChannelByPlatformErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByIdChannelByPlatformError = PutBotsByIdChannelByPlatformErrors[keyof PutBotsByIdChannelByPlatformErrors]; + +export type PutBotsByIdChannelByPlatformResponses = { + /** + * OK + */ + 200: ChannelChannelConfig; +}; + +export type PutBotsByIdChannelByPlatformResponse = PutBotsByIdChannelByPlatformResponses[keyof PutBotsByIdChannelByPlatformResponses]; + +export type PostBotsByIdChannelByPlatformSendData = { + /** + * Send payload + */ + body: ChannelSendRequest; + path: { + /** + * Bot ID + */ + id: string; + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/bots/{id}/channel/{platform}/send'; +}; + +export type PostBotsByIdChannelByPlatformSendErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByIdChannelByPlatformSendError = PostBotsByIdChannelByPlatformSendErrors[keyof PostBotsByIdChannelByPlatformSendErrors]; + +export type PostBotsByIdChannelByPlatformSendResponses = { + /** + * OK + */ + 200: { + [key: string]: string; + }; +}; + +export type PostBotsByIdChannelByPlatformSendResponse = PostBotsByIdChannelByPlatformSendResponses[keyof PostBotsByIdChannelByPlatformSendResponses]; + +export type PostBotsByIdChannelByPlatformSendSessionData = { + /** + * Send payload + */ + body: ChannelSendRequest; + path: { + /** + * Bot ID + */ + id: string; + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/bots/{id}/channel/{platform}/send_session'; +}; + +export type PostBotsByIdChannelByPlatformSendSessionErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Unauthorized + */ + 401: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostBotsByIdChannelByPlatformSendSessionError = PostBotsByIdChannelByPlatformSendSessionErrors[keyof PostBotsByIdChannelByPlatformSendSessionErrors]; + +export type PostBotsByIdChannelByPlatformSendSessionResponses = { + /** + * OK + */ + 200: { + [key: string]: string; + }; +}; + +export type PostBotsByIdChannelByPlatformSendSessionResponse = PostBotsByIdChannelByPlatformSendSessionResponses[keyof PostBotsByIdChannelByPlatformSendSessionResponses]; + +export type GetBotsByIdMembersData = { + body?: never; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}/members'; +}; + +export type GetBotsByIdMembersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetBotsByIdMembersError = GetBotsByIdMembersErrors[keyof GetBotsByIdMembersErrors]; + +export type GetBotsByIdMembersResponses = { + /** + * OK + */ + 200: BotsListMembersResponse; +}; + +export type GetBotsByIdMembersResponse = GetBotsByIdMembersResponses[keyof GetBotsByIdMembersResponses]; + +export type PutBotsByIdMembersData = { + /** + * Member payload + */ + body: BotsUpsertMemberRequest; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}/members'; +}; + +export type PutBotsByIdMembersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByIdMembersError = PutBotsByIdMembersErrors[keyof PutBotsByIdMembersErrors]; + +export type PutBotsByIdMembersResponses = { + /** + * OK + */ + 200: BotsBotMember; +}; + +export type PutBotsByIdMembersResponse = PutBotsByIdMembersResponses[keyof PutBotsByIdMembersResponses]; + +export type DeleteBotsByIdMembersByUserIdData = { + body?: never; + path: { + /** + * Bot ID + */ + id: string; + /** + * User ID + */ + user_id: string; + }; + query?: never; + url: '/bots/{id}/members/{user_id}'; +}; + +export type DeleteBotsByIdMembersByUserIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteBotsByIdMembersByUserIdError = DeleteBotsByIdMembersByUserIdErrors[keyof DeleteBotsByIdMembersByUserIdErrors]; + +export type DeleteBotsByIdMembersByUserIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type PutBotsByIdOwnerData = { + /** + * Transfer payload + */ + body: BotsTransferBotRequest; + path: { + /** + * Bot ID + */ + id: string; + }; + query?: never; + url: '/bots/{id}/owner'; +}; + +export type PutBotsByIdOwnerErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutBotsByIdOwnerError = PutBotsByIdOwnerErrors[keyof PutBotsByIdOwnerErrors]; + +export type PutBotsByIdOwnerResponses = { + /** + * OK + */ + 200: BotsBot; +}; + +export type PutBotsByIdOwnerResponse = PutBotsByIdOwnerResponses[keyof PutBotsByIdOwnerResponses]; + +export type GetChannelsData = { + body?: never; + path?: never; + query?: never; + url: '/channels'; +}; + +export type GetChannelsErrors = { + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetChannelsError = GetChannelsErrors[keyof GetChannelsErrors]; + +export type GetChannelsResponses = { + /** + * OK + */ + 200: Array; +}; + +export type GetChannelsResponse = GetChannelsResponses[keyof GetChannelsResponses]; + +export type GetChannelsByPlatformData = { + body?: never; + path: { + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/channels/{platform}'; +}; + +export type GetChannelsByPlatformErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; +}; + +export type GetChannelsByPlatformError = GetChannelsByPlatformErrors[keyof GetChannelsByPlatformErrors]; + +export type GetChannelsByPlatformResponses = { + /** + * OK + */ + 200: HandlersChannelMeta; +}; + +export type GetChannelsByPlatformResponse = GetChannelsByPlatformResponses[keyof GetChannelsByPlatformResponses]; + +export type PostEmbeddingsData = { + /** + * Embeddings request + */ + body: HandlersEmbeddingsRequest; + path?: never; + query?: never; + url: '/embeddings'; +}; + +export type PostEmbeddingsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; + /** + * Not Implemented + */ + 501: HandlersEmbeddingsResponse; +}; + +export type PostEmbeddingsError = PostEmbeddingsErrors[keyof PostEmbeddingsErrors]; + +export type PostEmbeddingsResponses = { + /** + * OK + */ + 200: HandlersEmbeddingsResponse; +}; + +export type PostEmbeddingsResponse = PostEmbeddingsResponses[keyof PostEmbeddingsResponses]; + +export type GetModelsData = { + body?: never; + path?: never; + query?: { + /** + * Model type (chat, embedding) + */ + type?: string; + /** + * Client type (openai, anthropic, google) + */ + client_type?: string; + }; + url: '/models'; +}; + +export type GetModelsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetModelsError = GetModelsErrors[keyof GetModelsErrors]; + +export type GetModelsResponses = { + /** + * OK + */ + 200: Array; +}; + +export type GetModelsResponse = GetModelsResponses[keyof GetModelsResponses]; + +export type PostModelsData = { + /** + * Model configuration + */ + body: ModelsAddRequest; + path?: never; + query?: never; + url: '/models'; +}; + +export type PostModelsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostModelsError = PostModelsErrors[keyof PostModelsErrors]; + +export type PostModelsResponses = { + /** + * Created + */ + 201: ModelsAddResponse; +}; + +export type PostModelsResponse = PostModelsResponses[keyof PostModelsResponses]; + +export type GetModelsCountData = { + body?: never; + path?: never; + query?: { + /** + * Model type (chat, embedding) + */ + type?: string; + }; + url: '/models/count'; +}; + +export type GetModelsCountErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetModelsCountError = GetModelsCountErrors[keyof GetModelsCountErrors]; + +export type GetModelsCountResponses = { + /** + * OK + */ + 200: ModelsCountResponse; +}; + +export type GetModelsCountResponse = GetModelsCountResponses[keyof GetModelsCountResponses]; + +export type PostModelsEnableData = { + /** + * Enable model payload + */ + body: HandlersEnableModelRequest; + path?: never; + query?: never; + url: '/models/enable'; +}; + +export type PostModelsEnableErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostModelsEnableError = PostModelsEnableErrors[keyof PostModelsEnableErrors]; + +export type PostModelsEnableResponses = { + /** + * OK + */ + 200: SettingsSettings; +}; + +export type PostModelsEnableResponse = PostModelsEnableResponses[keyof PostModelsEnableResponses]; + +export type DeleteModelsModelByModelIdData = { + body?: never; + path: { + /** + * Model ID (e.g., gpt-4) + */ + modelId: string; + }; + query?: never; + url: '/models/model/{modelId}'; +}; + +export type DeleteModelsModelByModelIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteModelsModelByModelIdError = DeleteModelsModelByModelIdErrors[keyof DeleteModelsModelByModelIdErrors]; + +export type DeleteModelsModelByModelIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetModelsModelByModelIdData = { + body?: never; + path: { + /** + * Model ID (e.g., gpt-4) + */ + modelId: string; + }; + query?: never; + url: '/models/model/{modelId}'; +}; + +export type GetModelsModelByModelIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetModelsModelByModelIdError = GetModelsModelByModelIdErrors[keyof GetModelsModelByModelIdErrors]; + +export type GetModelsModelByModelIdResponses = { + /** + * OK + */ + 200: ModelsGetResponse; +}; + +export type GetModelsModelByModelIdResponse = GetModelsModelByModelIdResponses[keyof GetModelsModelByModelIdResponses]; + +export type PutModelsModelByModelIdData = { + /** + * Updated model configuration + */ + body: ModelsUpdateRequest; + path: { + /** + * Model ID (e.g., gpt-4) + */ + modelId: string; + }; + query?: never; + url: '/models/model/{modelId}'; +}; + +export type PutModelsModelByModelIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutModelsModelByModelIdError = PutModelsModelByModelIdErrors[keyof PutModelsModelByModelIdErrors]; + +export type PutModelsModelByModelIdResponses = { + /** + * OK + */ + 200: ModelsGetResponse; +}; + +export type PutModelsModelByModelIdResponse = PutModelsModelByModelIdResponses[keyof PutModelsModelByModelIdResponses]; + +export type DeleteModelsByIdData = { + body?: never; + path: { + /** + * Model internal ID (UUID) + */ + id: string; + }; + query?: never; + url: '/models/{id}'; +}; + +export type DeleteModelsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteModelsByIdError = DeleteModelsByIdErrors[keyof DeleteModelsByIdErrors]; + +export type DeleteModelsByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetModelsByIdData = { + body?: never; + path: { + /** + * Model internal ID (UUID) + */ + id: string; + }; + query?: never; + url: '/models/{id}'; +}; + +export type GetModelsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetModelsByIdError = GetModelsByIdErrors[keyof GetModelsByIdErrors]; + +export type GetModelsByIdResponses = { + /** + * OK + */ + 200: ModelsGetResponse; +}; + +export type GetModelsByIdResponse = GetModelsByIdResponses[keyof GetModelsByIdResponses]; + +export type PutModelsByIdData = { + /** + * Updated model configuration + */ + body: ModelsUpdateRequest; + path: { + /** + * Model internal ID (UUID) + */ + id: string; + }; + query?: never; + url: '/models/{id}'; +}; + +export type PutModelsByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutModelsByIdError = PutModelsByIdErrors[keyof PutModelsByIdErrors]; + +export type PutModelsByIdResponses = { + /** + * OK + */ + 200: ModelsGetResponse; +}; + +export type PutModelsByIdResponse = PutModelsByIdResponses[keyof PutModelsByIdResponses]; + +export type GetProvidersData = { + body?: never; + path?: never; + query?: { + /** + * Client type filter (openai, anthropic, google, ollama) + */ + client_type?: string; + }; + url: '/providers'; +}; + +export type GetProvidersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetProvidersError = GetProvidersErrors[keyof GetProvidersErrors]; + +export type GetProvidersResponses = { + /** + * OK + */ + 200: Array; +}; + +export type GetProvidersResponse = GetProvidersResponses[keyof GetProvidersResponses]; + +export type PostProvidersData = { + /** + * Provider configuration + */ + body: ProvidersCreateRequest; + path?: never; + query?: never; + url: '/providers'; +}; + +export type PostProvidersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostProvidersError = PostProvidersErrors[keyof PostProvidersErrors]; + +export type PostProvidersResponses = { + /** + * Created + */ + 201: ProvidersGetResponse; +}; + +export type PostProvidersResponse = PostProvidersResponses[keyof PostProvidersResponses]; + +export type GetProvidersCountData = { + body?: never; + path?: never; + query?: { + /** + * Client type filter (openai, anthropic, google, ollama) + */ + client_type?: string; + }; + url: '/providers/count'; +}; + +export type GetProvidersCountErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetProvidersCountError = GetProvidersCountErrors[keyof GetProvidersCountErrors]; + +export type GetProvidersCountResponses = { + /** + * OK + */ + 200: ProvidersCountResponse; +}; + +export type GetProvidersCountResponse = GetProvidersCountResponses[keyof GetProvidersCountResponses]; + +export type GetProvidersNameByNameData = { + body?: never; + path: { + /** + * Provider name + */ + name: string; + }; + query?: never; + url: '/providers/name/{name}'; +}; + +export type GetProvidersNameByNameErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetProvidersNameByNameError = GetProvidersNameByNameErrors[keyof GetProvidersNameByNameErrors]; + +export type GetProvidersNameByNameResponses = { + /** + * OK + */ + 200: ProvidersGetResponse; +}; + +export type GetProvidersNameByNameResponse = GetProvidersNameByNameResponses[keyof GetProvidersNameByNameResponses]; + +export type DeleteProvidersByIdData = { + body?: never; + path: { + /** + * Provider ID (UUID) + */ + id: string; + }; + query?: never; + url: '/providers/{id}'; +}; + +export type DeleteProvidersByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type DeleteProvidersByIdError = DeleteProvidersByIdErrors[keyof DeleteProvidersByIdErrors]; + +export type DeleteProvidersByIdResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetProvidersByIdData = { + body?: never; + path: { + /** + * Provider ID (UUID) + */ + id: string; + }; + query?: never; + url: '/providers/{id}'; +}; + +export type GetProvidersByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetProvidersByIdError = GetProvidersByIdErrors[keyof GetProvidersByIdErrors]; + +export type GetProvidersByIdResponses = { + /** + * OK + */ + 200: ProvidersGetResponse; +}; + +export type GetProvidersByIdResponse = GetProvidersByIdResponses[keyof GetProvidersByIdResponses]; + +export type PutProvidersByIdData = { + /** + * Updated provider configuration + */ + body: ProvidersUpdateRequest; + path: { + /** + * Provider ID (UUID) + */ + id: string; + }; + query?: never; + url: '/providers/{id}'; +}; + +export type PutProvidersByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutProvidersByIdError = PutProvidersByIdErrors[keyof PutProvidersByIdErrors]; + +export type PutProvidersByIdResponses = { + /** + * OK + */ + 200: ProvidersGetResponse; +}; + +export type PutProvidersByIdResponse = PutProvidersByIdResponses[keyof PutProvidersByIdResponses]; + +export type GetProvidersByIdModelsData = { + body?: never; + path: { + /** + * Provider ID (UUID) + */ + id: string; + }; + query?: { + /** + * Model type (chat, embedding) + */ + type?: string; + }; + url: '/providers/{id}/models'; +}; + +export type GetProvidersByIdModelsErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetProvidersByIdModelsError = GetProvidersByIdModelsErrors[keyof GetProvidersByIdModelsErrors]; + +export type GetProvidersByIdModelsResponses = { + /** + * OK + */ + 200: Array; +}; + +export type GetProvidersByIdModelsResponse = GetProvidersByIdModelsResponses[keyof GetProvidersByIdModelsResponses]; + +export type GetUsersData = { + body?: never; + path?: never; + query?: never; + url: '/users'; +}; + +export type GetUsersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetUsersError = GetUsersErrors[keyof GetUsersErrors]; + +export type GetUsersResponses = { + /** + * OK + */ + 200: UsersListUsersResponse; +}; + +export type GetUsersResponse = GetUsersResponses[keyof GetUsersResponses]; + +export type PostUsersData = { + /** + * User payload + */ + body: UsersCreateUserRequest; + path?: never; + query?: never; + url: '/users'; +}; + +export type PostUsersErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PostUsersError = PostUsersErrors[keyof PostUsersErrors]; + +export type PostUsersResponses = { + /** + * Created + */ + 201: UsersUser; +}; + +export type PostUsersResponse = PostUsersResponses[keyof PostUsersResponses]; + +export type GetUsersMeData = { + body?: never; + path?: never; + query?: never; + url: '/users/me'; +}; + +export type GetUsersMeErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetUsersMeError = GetUsersMeErrors[keyof GetUsersMeErrors]; + +export type GetUsersMeResponses = { + /** + * OK + */ + 200: UsersUser; +}; + +export type GetUsersMeResponse = GetUsersMeResponses[keyof GetUsersMeResponses]; + +export type PutUsersMeData = { + /** + * Profile payload + */ + body: UsersUpdateProfileRequest; + path?: never; + query?: never; + url: '/users/me'; +}; + +export type PutUsersMeErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutUsersMeError = PutUsersMeErrors[keyof PutUsersMeErrors]; + +export type PutUsersMeResponses = { + /** + * OK + */ + 200: UsersUser; +}; + +export type PutUsersMeResponse = PutUsersMeResponses[keyof PutUsersMeResponses]; + +export type GetUsersMeChannelsByPlatformData = { + body?: never; + path: { + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/users/me/channels/{platform}'; +}; + +export type GetUsersMeChannelsByPlatformErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetUsersMeChannelsByPlatformError = GetUsersMeChannelsByPlatformErrors[keyof GetUsersMeChannelsByPlatformErrors]; + +export type GetUsersMeChannelsByPlatformResponses = { + /** + * OK + */ + 200: ChannelChannelUserBinding; +}; + +export type GetUsersMeChannelsByPlatformResponse = GetUsersMeChannelsByPlatformResponses[keyof GetUsersMeChannelsByPlatformResponses]; + +export type PutUsersMeChannelsByPlatformData = { + /** + * Channel user config payload + */ + body: ChannelUpsertUserConfigRequest; + path: { + /** + * Channel platform + */ + platform: string; + }; + query?: never; + url: '/users/me/channels/{platform}'; +}; + +export type PutUsersMeChannelsByPlatformErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutUsersMeChannelsByPlatformError = PutUsersMeChannelsByPlatformErrors[keyof PutUsersMeChannelsByPlatformErrors]; + +export type PutUsersMeChannelsByPlatformResponses = { + /** + * OK + */ + 200: ChannelChannelUserBinding; +}; + +export type PutUsersMeChannelsByPlatformResponse = PutUsersMeChannelsByPlatformResponses[keyof PutUsersMeChannelsByPlatformResponses]; + +export type PutUsersMePasswordData = { + /** + * Password payload + */ + body: UsersUpdatePasswordRequest; + path?: never; + query?: never; + url: '/users/me/password'; +}; + +export type PutUsersMePasswordErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutUsersMePasswordError = PutUsersMePasswordErrors[keyof PutUsersMePasswordErrors]; + +export type PutUsersMePasswordResponses = { + /** + * No Content + */ + 204: unknown; +}; + +export type GetUsersByIdData = { + body?: never; + path: { + /** + * User ID + */ + id: string; + }; + query?: never; + url: '/users/{id}'; +}; + +export type GetUsersByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type GetUsersByIdError = GetUsersByIdErrors[keyof GetUsersByIdErrors]; + +export type GetUsersByIdResponses = { + /** + * OK + */ + 200: UsersUser; +}; + +export type GetUsersByIdResponse = GetUsersByIdResponses[keyof GetUsersByIdResponses]; + +export type PutUsersByIdData = { + /** + * User update payload + */ + body: UsersUpdateUserRequest; + path: { + /** + * User ID + */ + id: string; + }; + query?: never; + url: '/users/{id}'; +}; + +export type PutUsersByIdErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutUsersByIdError = PutUsersByIdErrors[keyof PutUsersByIdErrors]; + +export type PutUsersByIdResponses = { + /** + * OK + */ + 200: UsersUser; +}; + +export type PutUsersByIdResponse = PutUsersByIdResponses[keyof PutUsersByIdResponses]; + +export type PutUsersByIdPasswordData = { + /** + * Password payload + */ + body: UsersResetPasswordRequest; + path: { + /** + * User ID + */ + id: string; + }; + query?: never; + url: '/users/{id}/password'; +}; + +export type PutUsersByIdPasswordErrors = { + /** + * Bad Request + */ + 400: HandlersErrorResponse; + /** + * Forbidden + */ + 403: HandlersErrorResponse; + /** + * Not Found + */ + 404: HandlersErrorResponse; + /** + * Internal Server Error + */ + 500: HandlersErrorResponse; +}; + +export type PutUsersByIdPasswordError = PutUsersByIdPasswordErrors[keyof PutUsersByIdPasswordErrors]; + +export type PutUsersByIdPasswordResponses = { + /** + * No Content + */ + 204: unknown; +}; diff --git a/packages/shared/README.md b/packages/shared/README.md deleted file mode 100644 index 6554adbe..00000000 --- a/packages/shared/README.md +++ /dev/null @@ -1 +0,0 @@ -# @memoh/shared diff --git a/packages/shared/package.json b/packages/shared/package.json deleted file mode 100644 index 6e841596..00000000 --- a/packages/shared/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "@memoh/shared", - "version": "1.0.0", - "description": "", - "exports": { - ".": "./src/index.ts" - }, - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "packageManager": "pnpm@10.27.0" -} diff --git a/packages/shared/src/chatInfo.ts b/packages/shared/src/chatInfo.ts deleted file mode 100644 index 3a11d13b..00000000 --- a/packages/shared/src/chatInfo.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface robot{ - description: string - time: Date, - id: string | number, - type: string, - action: 'robot', - state:'thinking'|'generate'|'complete' -} - -export interface user{ - description: string, - time: Date, - id: number | string, - action:'user' -} \ No newline at end of file diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts deleted file mode 100644 index f23cc870..00000000 --- a/packages/shared/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './model' -export * from './schedule' -export * from './platform' -export * from './mcp' -export * from './chatInfo' diff --git a/packages/shared/src/mcp.ts b/packages/shared/src/mcp.ts deleted file mode 100644 index da2993b1..00000000 --- a/packages/shared/src/mcp.ts +++ /dev/null @@ -1,48 +0,0 @@ -export interface BaseMCPConnection { - type: string - name: string -} - -export interface StdioMCPConnection extends BaseMCPConnection { - type: 'stdio' - command: string - args: string[] - env: Record - cwd: string -} - -export interface BaseHTTPMCPConnection extends BaseMCPConnection { - url: string - headers: Record -} - -export interface HTTPMCPConnection extends BaseHTTPMCPConnection { - type: 'http' -} - -export interface SSEMCPConnection extends BaseHTTPMCPConnection { - type: 'sse' -} - -export type MCPConnection = - | StdioMCPConnection - | HTTPMCPConnection - | SSEMCPConnection - - -export interface MCPListItem{ - id: string; - type: string; - name: string; - config: { - cwd: string; - env: Record; - args: string[]; - type: string; - command: string; - }; - active: boolean; - user: string; - createdAt: string; - updatedAt: string; -} \ No newline at end of file diff --git a/packages/shared/src/model.ts b/packages/shared/src/model.ts deleted file mode 100644 index 56b0c6fd..00000000 --- a/packages/shared/src/model.ts +++ /dev/null @@ -1,101 +0,0 @@ -export enum ModelClientType { - OPENAI = 'openai', - ANTHROPIC = 'anthropic', - GOOGLE = 'google', -} - -export enum ModelType { - CHAT = 'chat', - EMBEDDING = 'embedding', -} - -export interface BaseModel { - /** - * @description The unique identifier for the model - * @example 'gpt-4o' - */ - modelId: string - - /** - * @description The base URL for the model - * @example 'https://api.openai.com/v1' - */ - baseUrl: string - - /** - * @description The API key for the model - * @example 'sk-1234567890' - */ - apiKey: string - - /** - * @description The client type for the model - * @enum {ModelClientType} - */ - clientType: ModelClientType - - /** - * @description The display name for the model - * @example 'GPT 4o' - */ - name?: string - - /** - * @description The model type - * @enum {ModelType} - * @default {ModelType.CHAT} - */ - type?: ModelType -} - -export interface EmbeddingModel extends BaseModel { - type?: ModelType.EMBEDDING - - /** - * @description The dimensions of the embedding - * @example 1536 - */ - dimensions: number -} - -export interface ChatModel extends BaseModel { - type?: ModelType.CHAT -} - -export type Model = EmbeddingModel | ChatModel - - -// 表格当中model的类型 -export interface ModelList { - apiKey: string, - baseUrl: string, - clientType: 'OpenAI' | 'Anthropic' | 'Google', - modelId: string, - name: string, - type: 'chat' | 'embedding', - id: string, - defaultChatModel: boolean, - defaultEmbeddingModel: boolean, - defaultSummaryModel: boolean -} - -export interface ProviderInfo{ - api_key: string; - base_url: string; - client_type: string; - metadata: Record<'additionalProp1',object>; - name: string; -} - -export interface ModelInfo{ - dimensions:number - is_multimodal:boolean - input?: string[] - llm_provider_id:string - model_id:string - name:string - type: string - enable_as?:string -} - -export const clientType = ['openai', 'anthropic', 'google', 'ollama'] as const diff --git a/packages/shared/src/platform.ts b/packages/shared/src/platform.ts deleted file mode 100644 index bc371c73..00000000 --- a/packages/shared/src/platform.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Platform { - id: string - name: string - // endpoint: string - config: Record - active: boolean -} \ No newline at end of file diff --git a/packages/shared/src/schedule.ts b/packages/shared/src/schedule.ts deleted file mode 100644 index e08ca076..00000000 --- a/packages/shared/src/schedule.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface Schedule { - id?: string - pattern: string - name: string - description: string - command: string - maxCalls?: number | null -} \ No newline at end of file diff --git a/packages/web/demo.md b/packages/web/demo.md deleted file mode 100644 index 163438bb..00000000 --- a/packages/web/demo.md +++ /dev/null @@ -1,44 +0,0 @@ -# Markdown 语法测试文档 - -## 1. 标题层级 -### 一级标题 -#### 二级标题 -##### 三级标题 -###### 六级标题 - -## 2. 文本格式 -**粗体文本** -*斜体文本* -~~删除线文本~~ -`代码片段` - -> 引用文本 -> 可以多行 - -## 3. 列表 - -### 无序列表 -- 项目一 -- 项目二 - - 子项目 -- 项目三 - -### 有序列表 -1. 第一步 -2. 第二步 -3. 第三步 - -## 4. 链接与图片 -[百度](https://www.baidu.com) -![Markdown Logo](https://markdown-here.com/img/icon256.png) - -## 5. 表格 -| 姓名 | 年龄 | 职业 | -|------|------|------| -| 张三 | 25 | 开发 | -| 李四 | 30 | 测试 | - -## 6. 代码块 -```python -def hello_world(): - print("Hello, World!") \ No newline at end of file diff --git a/packages/web/mise.toml b/packages/web/mise.toml index 82fe917e..78461797 100644 --- a/packages/web/mise.toml +++ b/packages/web/mise.toml @@ -2,13 +2,23 @@ alias = "dev" description = "Start web development server" run = "pnpm dev" -depends = ["//:pnpm-install"] +depends = [ + "//:pnpm-install", + "//:sdk-generate", +] [tasks.build] description = "Build web" run = "pnpm build" -depends = ["//:pnpm-install"] +depends = [ + "//:pnpm-install", + "//:sdk-generate", +] [tasks.start] description = "Start web" -run = "pnpm start" \ No newline at end of file +run = "pnpm start" +depends = [ + "//:pnpm-install", + "//:sdk-generate", +] \ No newline at end of file diff --git a/packages/web/package.json b/packages/web/package.json index 1e4c1b13..626e4107 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -9,8 +9,8 @@ "start": "vite preview" }, "dependencies": { - "@memoh/shared": "workspace:*", "@memoh/ui": "workspace:*", + "@memoh/sdk": "workspace:*", "@pinia/colada": "^0.21.1", "@tailwindcss/vite": "^4.1.18", "@tanstack/vue-table": "^8.21.3", diff --git a/packages/web/src/components/add-provider/index.vue b/packages/web/src/components/add-provider/index.vue index e198257c..3997c6dd 100644 --- a/packages/web/src/components/add-provider/index.vue +++ b/packages/web/src/components/add-provider/index.vue @@ -89,7 +89,7 @@ @@ -152,12 +152,22 @@ import { import { toTypedSchema } from '@vee-validate/zod' import z from 'zod' import { useForm } from 'vee-validate' -import { clientType } from '@memoh/shared' -import { useCreateProvider } from '@/composables/api/useProviders' +import { useMutation, useQueryCache } from '@pinia/colada' +import { postProviders } from '@memoh/sdk' +import type { ProvidersClientType } from '@memoh/sdk' + +const CLIENT_TYPES: ProvidersClientType[] = ['openai', 'openai-compat', 'anthropic', 'google', 'ollama'] const open = defineModel('open') -const { mutate: providerFetch, isLoading } = useCreateProvider() +const queryCache = useQueryCache() +const { mutate: providerFetch, isLoading } = useMutation({ + mutation: async (data: Record) => { + const { data: result } = await postProviders({ body: data as any, throwOnError: true }) + return result + }, + onSettled: () => queryCache.invalidateQueries({ key: ['providers'] }), +}) const providerSchema = toTypedSchema(z.object({ api_key: z.string().min(1), diff --git a/packages/web/src/components/chat-list/robot-chat/index.vue b/packages/web/src/components/chat-list/assistant-chat/index.vue similarity index 100% rename from packages/web/src/components/chat-list/robot-chat/index.vue rename to packages/web/src/components/chat-list/assistant-chat/index.vue diff --git a/packages/web/src/components/chat-list/index.vue b/packages/web/src/components/chat-list/index.vue index 1f6defc2..03a4ba82 100644 --- a/packages/web/src/components/chat-list/index.vue +++ b/packages/web/src/components/chat-list/index.vue @@ -4,16 +4,16 @@ class="flex flex-col gap-4" > @@ -21,14 +21,15 @@ diff --git a/packages/web/src/components/chat-list/user-chat/index.vue b/packages/web/src/components/chat-list/user-chat/index.vue index e8b24046..8e8a3512 100644 --- a/packages/web/src/components/chat-list/user-chat/index.vue +++ b/packages/web/src/components/chat-list/user-chat/index.vue @@ -4,14 +4,21 @@ class="leading-7 not-first:mt-6 max-w-[90%] ml-auto text-muted-foreground bg-[#F9F9F9] p-4 rounded-xl rounded-tr-none break-all dark:bg-[#1C1917] " > - {{ userSay.description }} + {{ textContent }}

\ No newline at end of file + +const textContent = computed(() => { + const block = props.message.blocks.find(b => b.type === 'text') + return block?.type === 'text' ? block.content : '' +}) + diff --git a/packages/web/src/components/create-mcp/index.vue b/packages/web/src/components/create-mcp/index.vue index 5b4b7894..9c37a57c 100644 --- a/packages/web/src/components/create-mcp/index.vue +++ b/packages/web/src/components/create-mcp/index.vue @@ -260,7 +260,7 @@ import z from 'zod' import { toTypedSchema } from '@vee-validate/zod' import { useForm } from 'vee-validate' import { ref, inject, watch } from 'vue' -import { type MCPListItem as MCPType } from '@memoh/shared' +import { type MCPListItem as MCPType } from '@/composables/api/useMcp' import { useKeyValueTags } from '@/composables/useKeyValueTags' import { useCreateOrUpdateMcp } from '@/composables/api/useMcp' diff --git a/packages/web/src/components/create-model/index.vue b/packages/web/src/components/create-model/index.vue index 3b48ba7c..a083503c 100644 --- a/packages/web/src/components/create-model/index.vue +++ b/packages/web/src/components/create-model/index.vue @@ -172,8 +172,9 @@ import { useForm } from 'vee-validate' import { inject, computed, watch, nextTick, type Ref, ref } from 'vue' import { toTypedSchema } from '@vee-validate/zod' import z from 'zod' -import { type ModelInfo } from '@memoh/shared' -import { useCreateModel, useUpdateModel } from '@/composables/api/useModels' +import { useMutation, useQueryCache } from '@pinia/colada' +import { postModels, putModelsModelByModelId } from '@memoh/sdk' +import type { ModelsGetResponse } from '@memoh/sdk' const formSchema = toTypedSchema(z.object({ type: z.string().min(1), @@ -191,7 +192,7 @@ const selectedType = computed(() => form.values.type || editInfo?.value?.type) const open = inject>('openModel', ref(false)) const title = inject>('openModelTitle', ref('title')) -const editInfo = inject>('openModelState', ref(null)) +const editInfo = inject>('openModelState', ref(null)) // 保存按钮:编辑模式直接可提交(表单已预填充,handleSubmit 内部会校验) // 新建模式需要必填字段有值 @@ -229,8 +230,25 @@ function onNameInput(e: Event) { const { id } = defineProps<{ id: string }>() -const { mutateAsync: createModel, isLoading: createLoading } = useCreateModel() -const { mutateAsync: updateModel, isLoading: updateLoading } = useUpdateModel() +const queryCache = useQueryCache() +const { mutateAsync: createModel, isLoading: createLoading } = useMutation({ + mutation: async (data: Record) => { + const { data: result } = await postModels({ body: data as any, throwOnError: true }) + return result + }, + onSettled: () => queryCache.invalidateQueries({ key: ['provider-models'] }), +}) +const { mutateAsync: updateModel, isLoading: updateLoading } = useMutation({ + mutation: async ({ modelId, data }: { modelId: string; data: Record }) => { + const { data: result } = await putModelsModelByModelId({ + path: { modelId }, + body: data as any, + throwOnError: true, + }) + return result + }, + onSettled: () => queryCache.invalidateQueries({ key: ['provider-models'] }), +}) const isLoading = computed(() => createLoading.value || updateLoading.value) async function addModel(e: Event) { diff --git a/packages/web/src/components/Sidebar/index.vue b/packages/web/src/components/sidebar/index.vue similarity index 100% rename from packages/web/src/components/Sidebar/index.vue rename to packages/web/src/components/sidebar/index.vue diff --git a/packages/web/src/composables/api/useBotSettings.ts b/packages/web/src/composables/api/useBotSettings.ts deleted file mode 100644 index 79082b61..00000000 --- a/packages/web/src/composables/api/useBotSettings.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { fetchApi } from '@/utils/request' -import { useQuery, useMutation, useQueryCache } from '@pinia/colada' -import type { Ref } from 'vue' - -// ---- Types ---- - -export interface BotSettings { - chat_model_id: string - memory_model_id: string - embedding_model_id: string - max_context_load_time: number - language: string - allow_guest: boolean -} - -export interface UpsertBotSettingsRequest { - chat_model_id?: string - memory_model_id?: string - embedding_model_id?: string - max_context_load_time?: number - language?: string - allow_guest?: boolean -} - -// ---- Query ---- - -export function useBotSettings(botId: Ref) { - return useQuery({ - key: () => ['bot-settings', botId.value], - query: () => fetchApi(`/bots/${botId.value}/settings`), - enabled: () => !!botId.value, - }) -} - -// ---- Mutation ---- - -export function useUpdateBotSettings(botId: Ref) { - const queryCache = useQueryCache() - return useMutation({ - mutation: (data: UpsertBotSettingsRequest) => fetchApi( - `/bots/${botId.value}/settings`, - { method: 'PUT', body: data }, - ), - onSettled: () => queryCache.invalidateQueries({ key: ['bot-settings', botId.value] }), - }) -} diff --git a/packages/web/src/composables/api/useMcp.ts b/packages/web/src/composables/api/useMcp.ts index fe09a4ff..5ba29910 100644 --- a/packages/web/src/composables/api/useMcp.ts +++ b/packages/web/src/composables/api/useMcp.ts @@ -1,9 +1,24 @@ import { fetchApi } from '@/utils/request' import { useQuery, useMutation, useQueryCache } from '@pinia/colada' -import { type MCPListItem } from '@memoh/shared' - // ---- Types ---- +export interface MCPListItem { + id: string + type: string + name: string + config: { + cwd: string + env: Record + args: string[] + type: string + command: string + } + active: boolean + user: string + createdAt: string + updatedAt: string +} + export interface McpListResponse { items: MCPListItem[] } diff --git a/packages/web/src/composables/api/useModels.ts b/packages/web/src/composables/api/useModels.ts deleted file mode 100644 index 27b459fd..00000000 --- a/packages/web/src/composables/api/useModels.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { fetchApi } from '@/utils/request' -import { useQuery, useMutation, useQueryCache } from '@pinia/colada' -import { type ModelInfo } from '@memoh/shared' -import type { Ref } from 'vue' - -// ---- Types ---- - -export interface CreateModelRequest { - model_id: string - type: string - llm_provider_id: string - name?: string - dimensions?: number - is_multimodal?: boolean -} - -// ---- Query: 获取 Provider 下的模型列表 ---- - -export function useModelList(providerId: Ref) { - const queryCache = useQueryCache() - - const query = useQuery({ - key: ['model'], - query: () => fetchApi( - `/providers/${providerId.value}/models`, - ), - }) - - return { - ...query, - /** 当 providerId 变化时手动刷新 */ - invalidate: () => queryCache.invalidateQueries({ key: ['model'] }), - } -} - -// ---- Query: 获取所有模型(跨 Provider) ---- - -export function useAllModels() { - return useQuery({ - key: ['all-models'], - query: () => fetchApi('/models'), - }) -} - -// ---- Mutations ---- - -export function useCreateModel() { - const queryCache = useQueryCache() - return useMutation({ - mutation: (data: CreateModelRequest) => fetchApi('/models', { - method: 'POST', - body: data, - }), - onSettled: () => queryCache.invalidateQueries({ key: ['model'], exact: true }), - }) -} - -export function useUpdateModel() { - const queryCache = useQueryCache() - return useMutation({ - mutation: ({ modelId, data }: { modelId: string; data: Partial }) => - fetchApi(`/models/model/${modelId}`, { - method: 'PUT', - body: data, - }), - onSettled: () => queryCache.invalidateQueries({ key: ['model'] }), - }) -} - -export function useDeleteModel() { - const queryCache = useQueryCache() - return useMutation({ - mutation: (modelName: string) => fetchApi(`/models/model/${modelName}`, { - method: 'DELETE', - }), - onSettled: () => queryCache.invalidateQueries({ key: ['model'] }), - }) -} diff --git a/packages/web/src/composables/api/useProviders.ts b/packages/web/src/composables/api/useProviders.ts deleted file mode 100644 index a1f3f547..00000000 --- a/packages/web/src/composables/api/useProviders.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { fetchApi } from '@/utils/request' -import { useQuery, useMutation, useQueryCache } from '@pinia/colada' -import { type ProviderInfo } from '@memoh/shared' -import type { Ref } from 'vue' - -// ---- Types ---- - -export type ProviderWithId = ProviderInfo & { id: string } - -export interface CreateProviderRequest { - name: string - api_key: string - base_url: string - client_type: string - metadata?: Record -} - -export type UpdateProviderRequest = Partial - -// ---- Query: 获取 Provider 列表 ---- - -export function useProviderList(clientType: Ref) { - return useQuery({ - key: ['provider'], - query: () => fetchApi( - `/providers?client_type=${clientType.value}`, - ), - }) -} - -/** 获取所有 Provider(无过滤) */ -export function useAllProviders() { - return useQuery({ - key: ['all-providers'], - query: () => fetchApi('/providers'), - }) -} - -// ---- Mutations ---- - -export function useCreateProvider() { - const queryCache = useQueryCache() - return useMutation({ - mutation: (data: CreateProviderRequest) => fetchApi('/providers', { - method: 'POST', - body: data, - }), - onSettled: () => queryCache.invalidateQueries({ key: ['provider'] }), - }) -} - -export function useUpdateProvider(providerId: Ref) { - const queryCache = useQueryCache() - return useMutation({ - mutation: (data: UpdateProviderRequest) => fetchApi(`/providers/${providerId.value}`, { - method: 'PUT', - body: data, - }), - onSettled: () => queryCache.invalidateQueries({ key: ['provider'] }), - }) -} - -export function useDeleteProvider(providerId: Ref) { - const queryCache = useQueryCache() - return useMutation({ - mutation: () => fetchApi(`/providers/${providerId.value}`, { - method: 'DELETE', - }), - onSettled: () => queryCache.invalidateQueries({ key: ['provider'] }), - }) -} diff --git a/packages/web/src/lib/api-client.ts b/packages/web/src/lib/api-client.ts new file mode 100644 index 00000000..e92b4709 --- /dev/null +++ b/packages/web/src/lib/api-client.ts @@ -0,0 +1,29 @@ +import { client } from '@memoh/sdk/client' +import router from '@/router' + +/** + * Configure the SDK client with base URL, auth interceptor, and 401 handling. + * Call this once at app startup (main.ts). + */ +export function setupApiClient() { + // Set base URL to match the Vite proxy + client.setConfig({ baseUrl: '/api' }) + + // Add auth token to every request + client.interceptors.request.use((request) => { + const token = localStorage.getItem('token') + if (token) { + request.headers.set('Authorization', `Bearer ${token}`) + } + return request + }) + + // Handle 401 responses globally + client.interceptors.response.use((response) => { + if (response.status === 401) { + localStorage.removeItem('token') + router.replace({ name: 'Login' }) + } + return response + }) +} diff --git a/packages/web/src/main.ts b/packages/web/src/main.ts index 14bfcf88..5671a047 100644 --- a/packages/web/src/main.ts +++ b/packages/web/src/main.ts @@ -2,6 +2,10 @@ import { createApp } from 'vue' import './style.css' import App from './App.vue' import router from './router' +import { setupApiClient } from './lib/api-client' + +// Configure SDK client before anything else +setupApiClient() import { createPinia } from 'pinia' import i18n from './i18n' import { PiniaColada } from '@pinia/colada' diff --git a/packages/web/src/pages/bots/components/bot-card.vue b/packages/web/src/pages/bots/components/bot-card.vue index 33bb9b14..7a80cc64 100644 --- a/packages/web/src/pages/bots/components/bot-card.vue +++ b/packages/web/src/pages/bots/components/bot-card.vue @@ -80,17 +80,17 @@ import { import ConfirmPopover from '@/components/confirm-popover/index.vue' import { computed } from 'vue' import { useRouter } from 'vue-router' -import type { BotInfo } from '@/composables/api/useBots' +import type { BotsBot } from '@memoh/sdk' const router = useRouter() const props = defineProps<{ - bot: BotInfo + bot: BotsBot deleteLoading: boolean }>() defineEmits<{ - edit: [bot: BotInfo] + edit: [bot: BotsBot] delete: [id: string] }>() diff --git a/packages/web/src/pages/bots/components/bot-channels.vue b/packages/web/src/pages/bots/components/bot-channels.vue index 1bf2a8db..d333cba1 100644 --- a/packages/web/src/pages/bots/components/bot-channels.vue +++ b/packages/web/src/pages/bots/components/bot-channels.vue @@ -142,15 +142,48 @@ import { PopoverTrigger, PopoverContent, } from '@memoh/ui' -import { useBotChannels, type BotChannelItem } from '@/composables/api/useChannels' +import { useQuery, useQueryCache } from '@pinia/colada' +import { getChannels, getBotsByIdChannelByPlatform } from '@memoh/sdk' +import type { HandlersChannelMeta, ChannelChannelConfig } from '@memoh/sdk' import ChannelSettingsPanel from './channel-settings-panel.vue' +export interface BotChannelItem { + meta: HandlersChannelMeta + config: ChannelChannelConfig | null + configured: boolean +} + const props = defineProps<{ botId: string }>() const botIdRef = computed(() => props.botId) -const { data: channels, isLoading, refetch } = useBotChannels(botIdRef) + +const { data: channels, isLoading, refetch } = useQuery({ + key: () => ['bot-channels', botIdRef.value], + query: async (): Promise => { + const { data: metas } = await getChannels({ throwOnError: true }) + if (!metas) return [] + + const configurableTypes = metas.filter((m) => !m.configless) + + const results = await Promise.all( + configurableTypes.map(async (meta) => { + try { + const { data: config } = await getBotsByIdChannelByPlatform({ + path: { id: botIdRef.value, platform: meta.type }, + throwOnError: true, + }) + return { meta, config: config ?? null, configured: true } as BotChannelItem + } catch { + return { meta, config: null, configured: false } as BotChannelItem + } + }), + ) + return results + }, + enabled: () => !!botIdRef.value, +}) const selectedType = ref(null) const addPopoverOpen = ref(false) diff --git a/packages/web/src/pages/bots/components/bot-settings.vue b/packages/web/src/pages/bots/components/bot-settings.vue index 1ca1fddf..254c788c 100644 --- a/packages/web/src/pages/bots/components/bot-settings.vue +++ b/packages/web/src/pages/bots/components/bot-settings.vue @@ -103,9 +103,9 @@ import { reactive, computed, watch } from 'vue' import { toast } from 'vue-sonner' import { useI18n } from 'vue-i18n' import ModelSelect from './model-select.vue' -import { useBotSettings, useUpdateBotSettings, type BotSettings } from '@/composables/api/useBotSettings' -import { useAllModels } from '@/composables/api/useModels' -import { useAllProviders } from '@/composables/api/useProviders' +import { useQuery, useMutation, useQueryCache } from '@pinia/colada' +import { getBotsByBotIdSettings, putBotsByBotIdSettings, getModels, getProviders } from '@memoh/sdk' +import type { SettingsSettings } from '@memoh/sdk' import type { Ref } from 'vue' const props = defineProps<{ @@ -119,16 +119,50 @@ const botIdRef = computed(() => props.botId) as Ref const isPersonalBot = computed(() => props.botType.trim().toLowerCase() === 'personal') // ---- Data ---- -const { data: settings } = useBotSettings(botIdRef) -const { data: modelData } = useAllModels() -const { data: providerData } = useAllProviders() -const { mutateAsync: updateSettings, isLoading } = useUpdateBotSettings(botIdRef) +const queryCache = useQueryCache() + +const { data: settings } = useQuery({ + key: () => ['bot-settings', botIdRef.value], + query: async () => { + const { data } = await getBotsByBotIdSettings({ path: { bot_id: botIdRef.value }, throwOnError: true }) + return data + }, + enabled: () => !!botIdRef.value, +}) + +const { data: modelData } = useQuery({ + key: ['all-models'], + query: async () => { + const { data } = await getModels({ throwOnError: true }) + return data + }, +}) + +const { data: providerData } = useQuery({ + key: ['all-providers'], + query: async () => { + const { data } = await getProviders({ throwOnError: true }) + return data + }, +}) + +const { mutateAsync: updateSettings, isLoading } = useMutation({ + mutation: async (body: Partial) => { + const { data } = await putBotsByBotIdSettings({ + path: { bot_id: botIdRef.value }, + body, + throwOnError: true, + }) + return data + }, + onSettled: () => queryCache.invalidateQueries({ key: ['bot-settings', botIdRef.value] }), +}) const models = computed(() => modelData.value ?? []) const providers = computed(() => providerData.value ?? []) // ---- Form ---- -const form = reactive({ +const form = reactive({ chat_model_id: '', memory_model_id: '', embedding_model_id: '', diff --git a/packages/web/src/pages/bots/components/channel-settings-panel.vue b/packages/web/src/pages/bots/components/channel-settings-panel.vue index 4167a0bb..1ea5a59c 100644 --- a/packages/web/src/pages/bots/components/channel-settings-panel.vue +++ b/packages/web/src/pages/bots/components/channel-settings-panel.vue @@ -151,14 +151,17 @@ import { import { reactive, watch, computed } from 'vue' import { toast } from 'vue-sonner' import { useI18n } from 'vue-i18n' -import { - useUpsertBotChannel, - type BotChannelItem, - type FieldSchema, -} from '@/composables/api/useChannels' -import { ApiError } from '@/utils/request' +import { useMutation, useQueryCache } from '@pinia/colada' +import { putBotsByIdChannelByPlatform } from '@memoh/sdk' +import type { HandlersChannelMeta, ChannelChannelConfig, ChannelFieldSchema } from '@memoh/sdk' import type { Ref } from 'vue' +interface BotChannelItem { + meta: HandlersChannelMeta + config: ChannelChannelConfig | null + configured: boolean +} + const props = defineProps<{ botId: string channelItem: BotChannelItem @@ -170,7 +173,18 @@ const emit = defineEmits<{ const { t } = useI18n() const botIdRef = computed(() => props.botId) as Ref -const { mutateAsync: upsertChannel, isLoading } = useUpsertBotChannel(botIdRef) +const queryCache = useQueryCache() +const { mutateAsync: upsertChannel, isLoading } = useMutation({ + mutation: async ({ platform, data }: { platform: string; data: Record }) => { + const { data: result } = await putBotsByIdChannelByPlatform({ + path: { id: botIdRef.value, platform }, + body: data as any, + throwOnError: true, + }) + return result + }, + onSettled: () => queryCache.invalidateQueries({ key: ['bot-channels', botIdRef.value] }), +}) // ---- Form state ---- @@ -193,7 +207,7 @@ const orderedFields = computed(() => { if (!a.required && b.required) return 1 return 0 }) - return Object.fromEntries(entries) as Record + return Object.fromEntries(entries) as Record }) // 初始化表单 @@ -261,10 +275,7 @@ async function handleSave() { emit('saved') } catch (err) { let detail = '' - if (err instanceof ApiError && err.body) { - const body = err.body as Record - detail = String(body.message || body.error || '') - } else if (err instanceof Error) { + if (err instanceof Error) { detail = err.message } toast.error(detail ? `${t('bots.channels.saveFailed')}: ${detail}` : t('bots.channels.saveFailed')) diff --git a/packages/web/src/pages/bots/components/model-select.vue b/packages/web/src/pages/bots/components/model-select.vue index 2210c6ee..a9f36bc0 100644 --- a/packages/web/src/pages/bots/components/model-select.vue +++ b/packages/web/src/pages/bots/components/model-select.vue @@ -89,12 +89,11 @@ import { ScrollArea, } from '@memoh/ui' import { computed, ref, watch } from 'vue' -import type { ModelInfo } from '@memoh/shared' -import type { ProviderWithId } from '@/composables/api/useProviders' +import type { ModelsGetResponse, ProvidersGetResponse } from '@memoh/sdk' const props = defineProps<{ - models: ModelInfo[] - providers: ProviderWithId[] + models: ModelsGetResponse[] + providers: ProvidersGetResponse[] modelType: 'chat' | 'embedding' placeholder?: string }>() @@ -131,7 +130,7 @@ const filteredGroups = computed(() => { ) : typeFilteredModels.value - const groups = new Map() + const groups = new Map() for (const model of models) { const pid = model.llm_provider_id const providerName = providerMap.value.get(pid) ?? pid diff --git a/packages/web/src/pages/bots/detail.vue b/packages/web/src/pages/bots/detail.vue index cf3c613c..22c55a55 100644 --- a/packages/web/src/pages/bots/detail.vue +++ b/packages/web/src/pages/bots/detail.vue @@ -120,14 +120,22 @@ import { } from '@memoh/ui' import { computed, ref, watch } from 'vue' import { useRoute } from 'vue-router' -import { useBotDetail } from '@/composables/api/useBots' +import { useQuery } from '@pinia/colada' +import { getBotsById } from '@memoh/sdk' import BotSettings from './components/bot-settings.vue' import BotChannels from './components/bot-channels.vue' const route = useRoute() const botId = computed(() => route.params.botId as string) -const { data: bot } = useBotDetail(botId) +const { data: bot } = useQuery({ + key: () => ['bot', botId.value], + query: async () => { + const { data } = await getBotsById({ path: { id: botId.value }, throwOnError: true }) + return data + }, + enabled: () => !!botId.value, +}) // 加载到 bot 数据后,用名称替换 breadcrumb 中的 botId watch(bot, (val) => { diff --git a/packages/web/src/pages/bots/index.vue b/packages/web/src/pages/bots/index.vue index ae10dea1..72c93719 100644 --- a/packages/web/src/pages/bots/index.vue +++ b/packages/web/src/pages/bots/index.vue @@ -69,19 +69,25 @@ import { import { ref, computed } from 'vue' import BotCard from './components/bot-card.vue' import CreateBot from './components/create-bot.vue' -import { useBotList, useDeleteBot, type BotInfo } from '@/composables/api/useBots' +import { useQuery, useMutation, useQueryCache } from '@pinia/colada' +import { getBotsQuery, getBotsQueryKey, deleteBotsByIdMutation } from '@memoh/sdk/colada' +import type { BotsBot } from '@memoh/sdk' const searchText = ref('') const dialogOpen = ref(false) -const editingBot = ref(null) +const editingBot = ref(null) -const { data: botData, status } = useBotList() -const { mutate: deleteBot, isLoading: deleteLoading } = useDeleteBot() +const queryCache = useQueryCache() +const { data: botData, status } = useQuery(getBotsQuery()) +const { mutate: deleteBot, isLoading: deleteLoading } = useMutation({ + ...deleteBotsByIdMutation(), + onSettled: () => queryCache.invalidateQueries({ key: getBotsQueryKey() }), +}) const isLoading = computed(() => status.value === 'loading') const filteredBots = computed(() => { - const list = botData.value ?? [] + const list = botData.value?.items ?? [] const keyword = searchText.value.trim().toLowerCase() if (!keyword) return list return list.filter((bot) => @@ -91,14 +97,14 @@ const filteredBots = computed(() => { ) }) -function handleEdit(bot: BotInfo) { +function handleEdit(bot: BotsBot) { editingBot.value = bot dialogOpen.value = true } async function handleDelete(id: string) { try { - await deleteBot(id) + await deleteBot({ path: { id } }) } catch { return } diff --git a/packages/web/src/pages/chat/components/bot-sidebar.vue b/packages/web/src/pages/chat/components/bot-sidebar.vue index 894c0103..326a151e 100644 --- a/packages/web/src/pages/chat/components/bot-sidebar.vue +++ b/packages/web/src/pages/chat/components/bot-sidebar.vue @@ -65,17 +65,19 @@ diff --git a/packages/web/src/pages/models/components/model-item.vue b/packages/web/src/pages/models/components/model-item.vue index c607f56d..ea0f4ff6 100644 --- a/packages/web/src/pages/models/components/model-item.vue +++ b/packages/web/src/pages/models/components/model-item.vue @@ -43,15 +43,15 @@ import { Button, } from '@memoh/ui' import ConfirmPopover from '@/components/confirm-popover/index.vue' -import { type ModelInfo } from '@memoh/shared' +import type { ModelsGetResponse } from '@memoh/sdk' defineProps<{ - model: ModelInfo + model: ModelsGetResponse deleteLoading: boolean }>() defineEmits<{ - edit: [model: ModelInfo] + edit: [model: ModelsGetResponse] delete: [name: string] }>() diff --git a/packages/web/src/pages/models/components/model-list.vue b/packages/web/src/pages/models/components/model-list.vue index 9208e6cf..1efa935f 100644 --- a/packages/web/src/pages/models/components/model-list.vue +++ b/packages/web/src/pages/models/components/model-list.vue @@ -51,16 +51,16 @@ import { } from '@memoh/ui' import CreateModel from '@/components/create-model/index.vue' import ModelItem from './model-item.vue' -import { type ModelInfo } from '@memoh/shared' +import type { ModelsGetResponse } from '@memoh/sdk' defineProps<{ providerId: string | undefined - models: ModelInfo[] | undefined + models: ModelsGetResponse[] | undefined deleteModelLoading: boolean }>() defineEmits<{ - edit: [model: ModelInfo] + edit: [model: ModelsGetResponse] delete: [name: string] }>() diff --git a/packages/web/src/pages/models/components/provider-form.vue b/packages/web/src/pages/models/components/provider-form.vue index f43f7aa8..eb7253bf 100644 --- a/packages/web/src/pages/models/components/provider-form.vue +++ b/packages/web/src/pages/models/components/provider-form.vue @@ -100,10 +100,10 @@ import { computed, watch } from 'vue' import { toTypedSchema } from '@vee-validate/zod' import z from 'zod' import { useForm } from 'vee-validate' -import { type ProviderInfo } from '@memoh/shared' +import type { ProvidersGetResponse } from '@memoh/sdk' const props = defineProps<{ - provider: Partial | undefined + provider: Partial | undefined editLoading: boolean deleteLoading: boolean }>() diff --git a/packages/web/src/pages/models/model-setting.vue b/packages/web/src/pages/models/model-setting.vue index 992f06ad..2efab36f 100644 --- a/packages/web/src/pages/models/model-setting.vue +++ b/packages/web/src/pages/models/model-setting.vue @@ -32,21 +32,15 @@ import { Separator } from '@memoh/ui' import ProviderForm from './components/provider-form.vue' import ModelList from './components/model-list.vue' import { computed, inject, provide, reactive, ref, toRef, watch } from 'vue' -import { type ProviderInfo, type ModelInfo } from '@memoh/shared' -import { - useUpdateProvider, - useDeleteProvider, -} from '@/composables/api/useProviders' -import { - useModelList, - useDeleteModel, -} from '@/composables/api/useModels' +import { useQuery, useMutation, useQueryCache } from '@pinia/colada' +import { putProvidersById, deleteProvidersById, getProvidersByIdModels, deleteModelsModelByModelId } from '@memoh/sdk' +import type { ModelsGetResponse, ProvidersGetResponse } from '@memoh/sdk' // ---- Model 编辑状态(provide 给 CreateModel) ---- const openModel = reactive<{ state: boolean title: 'title' | 'edit' - curState: ModelInfo | null + curState: ModelsGetResponse | null }>({ state: false, title: 'title', @@ -57,23 +51,61 @@ provide('openModel', toRef(openModel, 'state')) provide('openModelTitle', toRef(openModel, 'title')) provide('openModelState', toRef(openModel, 'curState')) -function handleEditModel(model: ModelInfo) { +function handleEditModel(model: ModelsGetResponse) { openModel.state = true openModel.title = 'edit' openModel.curState = { ...model } } // ---- 当前 Provider ---- -const curProvider = inject('curProvider', ref>()) +const curProvider = inject('curProvider', ref()) const curProviderId = computed(() => curProvider.value?.id) // ---- API Hooks ---- -const { mutate: deleteProvider, isLoading: deleteLoading } = useDeleteProvider(curProviderId) -const { mutate: changeProvider, isLoading: editLoading } = useUpdateProvider(curProviderId) -const { mutate: deleteModel, isLoading: deleteModelLoading } = useDeleteModel() -const { data: modelDataList, invalidate: invalidateModels } = useModelList(curProviderId) +const queryCache = useQueryCache() + +const { mutate: deleteProvider, isLoading: deleteLoading } = useMutation({ + mutation: async () => { + if (!curProviderId.value) return + await deleteProvidersById({ path: { id: curProviderId.value }, throwOnError: true }) + }, + onSettled: () => queryCache.invalidateQueries({ key: ['providers'] }), +}) + +const { mutate: changeProvider, isLoading: editLoading } = useMutation({ + mutation: async (data: Record) => { + if (!curProviderId.value) return + const { data: result } = await putProvidersById({ + path: { id: curProviderId.value }, + body: data as any, + throwOnError: true, + }) + return result + }, + onSettled: () => queryCache.invalidateQueries({ key: ['providers'] }), +}) + +const { mutate: deleteModel, isLoading: deleteModelLoading } = useMutation({ + mutation: async (modelName: string) => { + await deleteModelsModelByModelId({ path: { modelId: modelName }, throwOnError: true }) + }, + onSettled: () => queryCache.invalidateQueries({ key: ['provider-models'] }), +}) + +const { data: modelDataList } = useQuery({ + key: () => ['provider-models', curProviderId.value ?? ''], + query: async () => { + if (!curProviderId.value) return [] + const { data } = await getProvidersByIdModels({ + path: { id: curProviderId.value }, + throwOnError: true, + }) + return data + }, + enabled: () => !!curProviderId.value, +}) watch(curProvider, () => { - invalidateModels() + queryCache.invalidateQueries({ key: ['provider-models'] }) }, { immediate: true }) diff --git a/packages/web/src/store/User.ts b/packages/web/src/store/user.ts similarity index 100% rename from packages/web/src/store/User.ts rename to packages/web/src/store/user.ts diff --git a/packages/web/src/types/index.ts b/packages/web/src/types/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/scripts/containerd-install.sh b/scripts/containerd-install.sh index 8551e3ed..c459f636 100755 --- a/scripts/containerd-install.sh +++ b/scripts/containerd-install.sh @@ -7,25 +7,97 @@ if [ "$(uname -s)" = "Darwin" ]; then exit $? fi -if command -v containerd >/dev/null 2>&1 && command -v nerdctl >/dev/null 2>&1; then +if command -v containerd >/dev/null 2>&1 && command -v nerdctl >/dev/null 2>&1 && command -v buildctl >/dev/null 2>&1 && command -v buildkitd >/dev/null 2>&1; then containerd --version nerdctl --version + buildctl --version exit 0 fi -if command -v apt-get >/dev/null 2>&1; then - sudo apt-get update - sudo apt-get install -y containerd nerdctl -elif command -v dnf >/dev/null 2>&1; then - sudo dnf install -y containerd nerdctl -elif command -v yum >/dev/null 2>&1; then - sudo yum install -y containerd nerdctl -elif command -v apk >/dev/null 2>&1; then - sudo apk add --no-cache containerd nerdctl -else - echo "No supported package manager found. Install containerd manually." - exit 1 +if ! command -v containerd >/dev/null 2>&1; then + if command -v apt-get >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y containerd + elif command -v dnf >/dev/null 2>&1; then + sudo dnf install -y containerd + elif command -v yum >/dev/null 2>&1; then + sudo yum install -y containerd + elif command -v apk >/dev/null 2>&1; then + sudo apk add --no-cache containerd + else + echo "No supported package manager found. Install containerd manually." + exit 1 + fi +fi + +if ! command -v nerdctl >/dev/null 2>&1 || ! command -v buildctl >/dev/null 2>&1 || ! command -v buildkitd >/dev/null 2>&1; then + OS="$(uname -s | tr '[:upper:]' '[:lower:]')" + ARCH="$(uname -m)" + NERDCTL_VERSION="${NERDCTL_VERSION:-}" + + if [ "$OS" != "linux" ]; then + echo "Automatic nerdctl installation from release is only supported on Linux." + exit 1 + fi + + case "$ARCH" in + x86_64|amd64) + ARCH="amd64" + ;; + aarch64|arm64) + ARCH="arm64" + ;; + *) + echo "Unsupported architecture for nerdctl release: $ARCH" + exit 1 + ;; + esac + + if [ -z "$NERDCTL_VERSION" ]; then + RELEASES_API_URL="https://api.github.com/repos/containerd/nerdctl/releases/latest" + if command -v curl >/dev/null 2>&1; then + NERDCTL_VERSION="$(curl -fsSL "$RELEASES_API_URL" | sed -n 's/.*"tag_name":[[:space:]]*"v\{0,1\}\([^"]*\)".*/\1/p' | head -n1)" + elif command -v wget >/dev/null 2>&1; then + NERDCTL_VERSION="$(wget -qO- "$RELEASES_API_URL" | sed -n 's/.*"tag_name":[[:space:]]*"v\{0,1\}\([^"]*\)".*/\1/p' | head -n1)" + fi + fi + + if [ -z "$NERDCTL_VERSION" ]; then + echo "Failed to detect latest nerdctl version. Set NERDCTL_VERSION manually." + exit 1 + fi + + NERDCTL_TARBALL="nerdctl-full-${NERDCTL_VERSION}-linux-${ARCH}.tar.gz" + NERDCTL_URL="https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/${NERDCTL_TARBALL}" + TMP_DIR="$(mktemp -d)" + TMP_TARBALL="${TMP_DIR}/${NERDCTL_TARBALL}" + + cleanup() { + rm -rf "$TMP_DIR" + } + trap cleanup EXIT INT TERM + + if command -v curl >/dev/null 2>&1; then + curl -fsSL "$NERDCTL_URL" -o "$TMP_TARBALL" + elif command -v wget >/dev/null 2>&1; then + wget -qO "$TMP_TARBALL" "$NERDCTL_URL" + else + echo "curl or wget is required to download nerdctl." + exit 1 + fi + + tar -xzf "$TMP_TARBALL" -C "$TMP_DIR" + sudo install -m 0755 "$TMP_DIR/bin/nerdctl" /usr/local/bin/nerdctl + sudo install -m 0755 "$TMP_DIR/bin/buildctl" /usr/local/bin/buildctl + sudo install -m 0755 "$TMP_DIR/bin/buildkitd" /usr/local/bin/buildkitd + + if command -v systemctl >/dev/null 2>&1 && [ -f "$TMP_DIR/lib/systemd/system/buildkit.service" ]; then + sudo install -m 0644 "$TMP_DIR/lib/systemd/system/buildkit.service" /etc/systemd/system/buildkit.service + sudo systemctl daemon-reload + sudo systemctl enable --now buildkit.service || true + fi fi containerd --version nerdctl --version +buildctl --version diff --git a/scripts/mcp-image-up.sh b/scripts/mcp-image-up.sh index d5636a8f..f849552d 100755 --- a/scripts/mcp-image-up.sh +++ b/scripts/mcp-image-up.sh @@ -4,7 +4,7 @@ set -e IMAGE="memoh-mcp:dev" if [ "$(uname -s)" = "Darwin" ]; then - limactl shell default -- nerdctl build -f cmd/mcp/Dockerfile -t "$IMAGE" . + limactl shell default -- nerdctl build -f docker/Dockerfile.mcp -t "$IMAGE" . # Import into rootful containerd so the Go agent can find the image limactl shell default -- sh -c "nerdctl save $IMAGE | sudo nerdctl load" exit $? @@ -15,4 +15,4 @@ if ! command -v nerdctl >/dev/null 2>&1; then exit 1 fi -nerdctl build -f cmd/mcp/Dockerfile -t "$IMAGE" . +nerdctl build -f docker/Dockerfile.mcp -t "$IMAGE" . diff --git a/docs/docs.go b/spec/docs.go similarity index 100% rename from docs/docs.go rename to spec/docs.go diff --git a/docs/swagger.json b/spec/swagger.json similarity index 100% rename from docs/swagger.json rename to spec/swagger.json diff --git a/docs/swagger.yaml b/spec/swagger.yaml similarity index 100% rename from docs/swagger.yaml rename to spec/swagger.yaml diff --git a/typos.toml b/typos.toml new file mode 100644 index 00000000..0ea8f769 --- /dev/null +++ b/typos.toml @@ -0,0 +1,7 @@ +[default.extend-words] + +[files] +extend-exclude = [ + "**/node_modules/**", + +] \ No newline at end of file