diff --git a/agent/package.json b/agent/package.json index c2a67ff0..14a9e51f 100644 --- a/agent/package.json +++ b/agent/package.json @@ -8,14 +8,10 @@ }, "dependencies": { "@memoh/config": "workspace:*", - "@ai-sdk/amazon-bedrock": "^4.0.56", "@ai-sdk/anthropic": "^3.0.9", - "@ai-sdk/azure": "^3.0.28", "@ai-sdk/google": "^3.0.6", "@ai-sdk/mcp": "^1.0.6", - "@ai-sdk/mistral": "^3.0.19", "@ai-sdk/openai": "^3.0.7", - "@ai-sdk/xai": "^3.0.54", "@elysiajs/bearer": "^1.4.2", "@elysiajs/cors": "^1.4.1", "@modelcontextprotocol/sdk": "^1.25.2", diff --git a/agent/src/model.ts b/agent/src/model.ts index d40ea6e1..738560ed 100644 --- a/agent/src/model.ts +++ b/agent/src/model.ts @@ -1,11 +1,6 @@ -import { createGateway as createAiGateway } from 'ai' import { createOpenAI } from '@ai-sdk/openai' import { createAnthropic } from '@ai-sdk/anthropic' import { createGoogleGenerativeAI } from '@ai-sdk/google' -import { createAzure } from '@ai-sdk/azure' -import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock' -import { createMistral } from '@ai-sdk/mistral' -import { createXai } from '@ai-sdk/xai' import { ClientType, ModelConfig } from './types' export const createModel = (model: ModelConfig) => { @@ -14,34 +9,16 @@ export const createModel = (model: ModelConfig) => { const modelId = model.modelId.trim() switch (model.clientType) { - case ClientType.OpenAI: + case ClientType.OpenAIResponses: return createOpenAI({ apiKey, baseURL })(modelId) - case ClientType.OpenAICompat: - case ClientType.Ollama: - case ClientType.Dashscope: { - // All OpenAI-compatible providers use .chat() for /chat/completions - const provider = createOpenAI({ apiKey, baseURL }) - return provider.chat(modelId) + case ClientType.OpenAICompletions: { + return createOpenAI({ apiKey, baseURL }).chat(modelId) } - case ClientType.Anthropic: + case ClientType.AnthropicMessages: return createAnthropic({ apiKey, baseURL })(modelId) - case ClientType.Google: + case ClientType.GoogleGenerativeAI: return createGoogleGenerativeAI({ apiKey, baseURL })(modelId) - case ClientType.Azure: - return createAzure({ apiKey, baseURL })(modelId) - case ClientType.Bedrock: { - // Bedrock uses AWS credentials; apiKey as accessKeyId, metadata for secretAccessKey - // Falls back to AWS default credential chain if not provided - const opts: Record = {} - if (baseURL) opts.region = baseURL - if (apiKey) opts.accessKeyId = apiKey - return createAmazonBedrock(opts)(modelId) - } - case ClientType.Mistral: - return createMistral({ apiKey, baseURL: baseURL || undefined })(modelId) - case ClientType.XAI: - return createXai({ apiKey, baseURL: baseURL || undefined })(modelId) default: - return createAiGateway({ apiKey, baseURL })(modelId) + return createOpenAI({ apiKey, baseURL }).chat(modelId) } -} \ No newline at end of file +} diff --git a/agent/src/models.ts b/agent/src/models.ts index a7fa6fcd..18a7968f 100644 --- a/agent/src/models.ts +++ b/agent/src/models.ts @@ -9,8 +9,7 @@ export const AgentSkillModel = z.object({ }) export const ClientTypeModel = z.enum([ - 'openai', 'openai-compat', 'anthropic', 'google', - 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope', + 'openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai', ]) export const ModelConfigModel = z.object({ diff --git a/agent/src/types/model.ts b/agent/src/types/model.ts index 937070ef..d50e616f 100644 --- a/agent/src/types/model.ts +++ b/agent/src/types/model.ts @@ -1,14 +1,8 @@ export enum ClientType { - OpenAI = 'openai', - OpenAICompat = 'openai-compat', - Anthropic = 'anthropic', - Google = 'google', - Azure = 'azure', - Bedrock = 'bedrock', - Mistral = 'mistral', - XAI = 'xai', - Ollama = 'ollama', - Dashscope = 'dashscope', + OpenAIResponses = 'openai-responses', + OpenAICompletions = 'openai-completions', + AnthropicMessages = 'anthropic-messages', + GoogleGenerativeAI = 'google-generative-ai', } export enum ModelInput { @@ -28,4 +22,4 @@ export interface ModelConfig { } export const hasInputModality = (config: ModelConfig, modality: ModelInput): boolean => - config.input.includes(modality) \ No newline at end of file + config.input.includes(modality) diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 29bddcce..7fce0013 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -681,12 +681,11 @@ func (c *lazyLLMClient) resolve(ctx context.Context) (memory.LLM, error) { if err != nil { return nil, err } - clientType := strings.ToLower(strings.TrimSpace(memoryProvider.ClientType)) + clientType := string(memoryModel.ClientType) switch clientType { - case "openai", "openai-compat", "azure", "mistral", "xai", "ollama", "dashscope": - // These providers support OpenAI-compatible /chat/completions endpoint + case "openai-responses", "openai-completions", "anthropic-messages", "google-generative-ai": default: - return nil, fmt.Errorf("memory provider client type not supported: %s", memoryProvider.ClientType) + return nil, fmt.Errorf("memory model client type not supported: %s", clientType) } return memory.NewLLMClient(c.logger, memoryProvider.BaseUrl, memoryProvider.ApiKey, memoryModel.ModelID, c.timeout) } diff --git a/db/migrations/0001_init.up.sql b/db/migrations/0001_init.up.sql index 77f83e16..15ea464f 100644 --- a/db/migrations/0001_init.up.sql +++ b/db/migrations/0001_init.up.sql @@ -59,14 +59,12 @@ CREATE INDEX IF NOT EXISTS idx_user_channel_bindings_user_id ON user_channel_bin CREATE TABLE IF NOT EXISTS llm_providers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name TEXT NOT NULL, - client_type TEXT NOT NULL, base_url TEXT NOT NULL, api_key TEXT NOT NULL, metadata JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), - CONSTRAINT llm_providers_name_unique UNIQUE (name), - CONSTRAINT llm_providers_client_type_check CHECK (client_type IN ('openai', 'openai-compat', 'anthropic', 'google', 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope')) + CONSTRAINT llm_providers_name_unique UNIQUE (name) ); CREATE TABLE IF NOT EXISTS search_providers ( @@ -85,6 +83,7 @@ CREATE TABLE IF NOT EXISTS models ( model_id TEXT NOT NULL, name TEXT, llm_provider_id UUID NOT NULL REFERENCES llm_providers(id) ON DELETE CASCADE, + client_type TEXT, dimensions INTEGER, input_modalities TEXT[] NOT NULL DEFAULT ARRAY['text']::TEXT[], type TEXT NOT NULL DEFAULT 'chat', @@ -92,7 +91,9 @@ CREATE TABLE IF NOT EXISTS models ( updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), CONSTRAINT models_model_id_unique UNIQUE (model_id), CONSTRAINT models_type_check CHECK (type IN ('chat', 'embedding')), - CONSTRAINT models_dimensions_check CHECK (type != 'embedding' OR dimensions IS NOT NULL) + CONSTRAINT models_dimensions_check CHECK (type != 'embedding' OR dimensions IS NOT NULL), + CONSTRAINT models_client_type_check CHECK (client_type IS NULL OR client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai')), + CONSTRAINT models_chat_client_type_check CHECK (type != 'chat' OR client_type IS NOT NULL) ); CREATE TABLE IF NOT EXISTS model_variants ( diff --git a/db/migrations/0010_client_type_to_model.down.sql b/db/migrations/0010_client_type_to_model.down.sql new file mode 100644 index 00000000..1cb19785 --- /dev/null +++ b/db/migrations/0010_client_type_to_model.down.sql @@ -0,0 +1,29 @@ +-- 0010_client_type_to_model (down) +-- Reverse: restore client_type on llm_providers, remove from models. + +-- 1) Re-add client_type to llm_providers (nullable first) +ALTER TABLE llm_providers ADD COLUMN IF NOT EXISTS client_type TEXT; + +-- 2) Reverse-map from models back to providers (only chat models have client_type) +UPDATE llm_providers SET client_type = CASE m.client_type + WHEN 'openai-responses' THEN 'openai' + WHEN 'openai-completions' THEN 'openai-compat' + WHEN 'anthropic-messages' THEN 'anthropic' + WHEN 'google-generative-ai' THEN 'google' +END +FROM models m +WHERE m.llm_provider_id = llm_providers.id + AND m.client_type IS NOT NULL; + +-- 3) Default any remaining NULLs to 'openai' +UPDATE llm_providers SET client_type = 'openai' WHERE client_type IS NULL; + +-- 4) Set NOT NULL + CHECK on providers +ALTER TABLE llm_providers ALTER COLUMN client_type SET NOT NULL; +ALTER TABLE llm_providers ADD CONSTRAINT llm_providers_client_type_check + CHECK (client_type IN ('openai', 'openai-compat', 'anthropic', 'google', 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope')); + +-- 5) Drop client_type from models +ALTER TABLE models DROP CONSTRAINT IF EXISTS models_chat_client_type_check; +ALTER TABLE models DROP CONSTRAINT IF EXISTS models_client_type_check; +ALTER TABLE models DROP COLUMN IF EXISTS client_type; diff --git a/db/migrations/0010_client_type_to_model.up.sql b/db/migrations/0010_client_type_to_model.up.sql new file mode 100644 index 00000000..9a2921a1 --- /dev/null +++ b/db/migrations/0010_client_type_to_model.up.sql @@ -0,0 +1,34 @@ +-- 0010_client_type_to_model +-- Move client_type from llm_providers to models, rename to new values, drop unsupported types. + +-- 1) Add client_type column to models (nullable) +ALTER TABLE models ADD COLUMN IF NOT EXISTS client_type TEXT; + +-- 2) Migrate data from provider to model with name mapping +UPDATE models SET client_type = CASE p.client_type + WHEN 'openai' THEN 'openai-responses' + WHEN 'openai-compat' THEN 'openai-completions' + WHEN 'anthropic' THEN 'anthropic-messages' + WHEN 'google' THEN 'google-generative-ai' +END +FROM llm_providers p +WHERE models.llm_provider_id = p.id + AND p.client_type IN ('openai', 'openai-compat', 'anthropic', 'google'); + +-- 3) Delete models whose provider had an unsupported client_type (still NULL after step 2, AND type is chat) +DELETE FROM models WHERE client_type IS NULL AND type = 'chat'; + +-- 4) For embedding models, leave client_type as NULL (they don't need one) + +-- 5) Delete providers with unsupported client_type +DELETE FROM llm_providers WHERE client_type NOT IN ('openai', 'openai-compat', 'anthropic', 'google'); + +-- 6) Add CHECK constraints: client_type values + chat models must have client_type +ALTER TABLE models ADD CONSTRAINT models_client_type_check + CHECK (client_type IS NULL OR client_type IN ('openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai')); +ALTER TABLE models ADD CONSTRAINT models_chat_client_type_check + CHECK (type != 'chat' OR client_type IS NOT NULL); + +-- 7) Drop client_type from llm_providers +ALTER TABLE llm_providers DROP CONSTRAINT IF EXISTS llm_providers_client_type_check; +ALTER TABLE llm_providers DROP COLUMN IF EXISTS client_type; diff --git a/db/queries/models.sql b/db/queries/models.sql index f1adc4ff..707d9ca6 100644 --- a/db/queries/models.sql +++ b/db/queries/models.sql @@ -1,8 +1,7 @@ -- name: CreateLlmProvider :one -INSERT INTO llm_providers (name, client_type, base_url, api_key, metadata) +INSERT INTO llm_providers (name, base_url, api_key, metadata) VALUES ( sqlc.arg(name), - sqlc.arg(client_type), sqlc.arg(base_url), sqlc.arg(api_key), sqlc.arg(metadata) @@ -19,16 +18,10 @@ SELECT * FROM llm_providers WHERE name = sqlc.arg(name); SELECT * FROM llm_providers ORDER BY created_at DESC; --- name: ListLlmProvidersByClientType :many -SELECT * FROM llm_providers -WHERE client_type = sqlc.arg(client_type) -ORDER BY created_at DESC; - -- name: UpdateLlmProvider :one UPDATE llm_providers SET name = sqlc.arg(name), - client_type = sqlc.arg(client_type), base_url = sqlc.arg(base_url), api_key = sqlc.arg(api_key), metadata = sqlc.arg(metadata), @@ -42,15 +35,13 @@ DELETE FROM llm_providers WHERE id = sqlc.arg(id); -- name: CountLlmProviders :one SELECT COUNT(*) FROM llm_providers; --- name: CountLlmProvidersByClientType :one -SELECT COUNT(*) FROM llm_providers WHERE client_type = sqlc.arg(client_type); - -- name: CreateModel :one -INSERT INTO models (model_id, name, llm_provider_id, dimensions, input_modalities, type) +INSERT INTO models (model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type) VALUES ( sqlc.arg(model_id), sqlc.arg(name), sqlc.arg(llm_provider_id), + sqlc.narg(client_type), sqlc.arg(dimensions), sqlc.arg(input_modalities), sqlc.arg(type) @@ -73,10 +64,9 @@ WHERE type = sqlc.arg(type) ORDER BY created_at DESC; -- name: ListModelsByClientType :many -SELECT m.* FROM models AS m -JOIN llm_providers AS p ON p.id = m.llm_provider_id -WHERE p.client_type = sqlc.arg(client_type) -ORDER BY m.created_at DESC; +SELECT * FROM models +WHERE client_type = sqlc.arg(client_type) +ORDER BY created_at DESC; -- name: ListModelsByProviderID :many SELECT * FROM models @@ -94,6 +84,7 @@ UPDATE models SET name = sqlc.arg(name), llm_provider_id = sqlc.arg(llm_provider_id), + client_type = sqlc.narg(client_type), dimensions = sqlc.arg(dimensions), input_modalities = sqlc.arg(input_modalities), type = sqlc.arg(type), @@ -107,6 +98,7 @@ SET model_id = sqlc.arg(new_model_id), name = sqlc.arg(name), llm_provider_id = sqlc.arg(llm_provider_id), + client_type = sqlc.narg(client_type), dimensions = sqlc.arg(dimensions), input_modalities = sqlc.arg(input_modalities), type = sqlc.arg(type), @@ -141,5 +133,3 @@ RETURNING *; SELECT * FROM model_variants WHERE model_uuid = sqlc.arg(model_uuid) ORDER BY weight DESC, created_at DESC; - - diff --git a/docs/docs/cli/model.md b/docs/docs/cli/model.md index a709e20c..e0d7b7c0 100644 --- a/docs/docs/cli/model.md +++ b/docs/docs/cli/model.md @@ -4,7 +4,7 @@ Manage chat and embedding models. ## model list -List all models with their provider, type, and multimodal flag. +List all models with their provider, type, client type, and multimodal flag. ```bash memoh model list @@ -12,7 +12,7 @@ memoh model list ## model create -Create a new model. Prompts for provider, model ID, type, and (for embedding models) dimensions. +Create a new model. Prompts for provider, model ID, type, client type, and (for embedding models) dimensions. ```bash memoh model create [options] @@ -23,6 +23,7 @@ memoh model create [options] | `--model_id ` | Model ID (e.g. `gpt-4`, `text-embedding-3-small`) | | `--name ` | Display name | | `--provider ` | Provider name | +| `--client_type ` | Client type: `openai-responses`, `openai-completions`, `anthropic-messages`, `google-generative-ai` | | `--type ` | `chat` or `embedding` | | `--dimensions ` | Embedding dimensions (required for embedding models) | | `--multimodal` | Mark as multimodal | @@ -30,8 +31,8 @@ memoh model create [options] Examples: ```bash -memoh model create --model_id gpt-4 --provider my-openai --type chat -memoh model create --model_id text-embedding-3-small --provider my-openai --type embedding --dimensions 1536 +memoh model create --model_id gpt-4 --provider my-openai --client_type openai-responses --type chat +memoh model create --model_id text-embedding-3-small --provider my-openai --client_type openai-completions --type embedding --dimensions 1536 memoh model create # Interactive prompts ``` diff --git a/docs/docs/cli/provider.md b/docs/docs/cli/provider.md index ab953560..d27ca984 100644 --- a/docs/docs/cli/provider.md +++ b/docs/docs/cli/provider.md @@ -1,6 +1,6 @@ # Provider Commands -Manage LLM providers (OpenAI, Anthropic, Ollama, etc.). +Manage LLM providers (API endpoints and credentials). ## provider list @@ -32,16 +32,13 @@ memoh provider create [options] | Option | Description | |--------|-------------| | `--name ` | Provider name | -| `--type ` | Client type | | `--base_url ` | Base URL for the API | | `--api_key ` | API key | -Supported client types: `openai`, `openai-compat`, `anthropic`, `google`, `azure`, `bedrock`, `mistral`, `xai`, `ollama`, `dashscope` - Examples: ```bash -memoh provider create --name my-ollama --type ollama --base_url http://localhost:11434 +memoh provider create --name my-ollama --base_url http://localhost:11434/v1 memoh provider create # Interactive prompts ``` diff --git a/docs/docs/concepts/provider-and-model.md b/docs/docs/concepts/provider-and-model.md index b9b86b00..d4d67e6e 100644 --- a/docs/docs/concepts/provider-and-model.md +++ b/docs/docs/concepts/provider-and-model.md @@ -2,8 +2,19 @@ In Memoh, **provider** and **model** are separate but connected concepts: -- A **provider** is the LLM service configuration (API endpoint, key, client type) -- A **model** is the concrete chat or embedding model under that provider +- A **provider** is the LLM service configuration (API endpoint and key) +- A **model** is the concrete chat or embedding model under that provider, including its **client type** which determines which API protocol to use + +## Client Types + +Each model has a `client_type` that determines how Memoh communicates with the LLM service: + +| Client Type | Description | +|-------------|-------------| +| `openai-responses` | OpenAI Responses API | +| `openai-completions` | OpenAI Chat Completions API (also works with compatible services like Ollama, Mistral, etc.) | +| `anthropic-messages` | Anthropic Messages API | +| `google-generative-ai` | Google Generative AI API | ## Typical Setup @@ -26,4 +37,3 @@ This enables per-bot customization (for quality, latency, or cost). - `Models > Add Provider > Select Provider > Add Model` - `Bots > Select a bot > Settings > Choose chat/memory/embedding models` - diff --git a/docs/docs/getting-started.md b/docs/docs/getting-started.md index 19807dd1..edeea781 100644 --- a/docs/docs/getting-started.md +++ b/docs/docs/getting-started.md @@ -46,10 +46,10 @@ Bots come with a rich set of built-in tools: ### Multi-LLM Provider Support -Flexibly switch between a wide range of LLM providers: +Flexibly switch between a wide range of LLM providers via four client types: -- OpenAI, Anthropic, Google, Azure, AWS Bedrock -- Mistral, XAI, Ollama, Dashscope (Qwen), and more +- OpenAI Responses API, OpenAI Chat Completions API (including compatible services) +- Anthropic Messages API, Google Generative AI API ### MCP Protocol Support diff --git a/docs/docs/getting-started/provider-and-model.md b/docs/docs/getting-started/provider-and-model.md index 09b8c387..af66fb75 100644 --- a/docs/docs/getting-started/provider-and-model.md +++ b/docs/docs/getting-started/provider-and-model.md @@ -14,7 +14,7 @@ Click **Models** in the left sidebar to open the Provider and Model configuratio ![Models page - sidebar](/getting-started/provider-model-01-sidebar.png) The page has two panels: -- **Left**: Provider list and filter +- **Left**: Provider list and search - **Right**: Selected provider's details and models (or an empty state if none selected) ## Step 2: Add a Provider @@ -30,7 +30,6 @@ In the dialog, fill in: | **Name** | A display name for this provider (e.g. `my-openai`, `ollama-local`) | | **API Key** | Your API key. For local services like Ollama, you can use a placeholder like `ollama` | | **Base URL** | The API base URL (e.g. `https://api.openai.com/v1`, `http://localhost:11434/v1` for Ollama) | -| **Type** | Client type: `openai`, `openai-compat`, `anthropic`, `google`, `azure`, `bedrock`, `mistral`, `xai`, `ollama`, `dashscope` | ![Add Provider dialog](/getting-started/provider-model-03-provider-dialog.png) @@ -38,13 +37,11 @@ In the dialog, fill in: - Name: `openai` - API Key: `sk-...` - Base URL: `https://api.openai.com/v1` -- Type: `openai` **Example — Ollama (local):** - Name: `ollama` - API Key: `ollama` - Base URL: `http://localhost:11434/v1` -- Type: `ollama` Click **Add** to save. The new provider appears in the left sidebar. @@ -60,6 +57,7 @@ Fill in: | Field | Description | |-------|-------------| +| **Client Type** | API protocol: `openai-responses`, `openai-completions`, `anthropic-messages`, or `google-generative-ai` | | **Type** | `chat` or `embedding` | | **Model** | Model ID (e.g. `gpt-4`, `llama3.2`, `text-embedding-3-small`) | | **Display Name** | Optional display name | @@ -71,8 +69,8 @@ Fill in: - One **embedding** model (for memory) Add them under the same or different providers. For example: -- Chat: `gpt-4` (OpenAI) or `llama3.2` (Ollama) -- Embedding: `text-embedding-3-small` (OpenAI) or `nomic-embed-text` (Ollama) +- Chat: `gpt-4` with client type `openai-responses` (OpenAI) or `llama3.2` with client type `openai-completions` (Ollama) +- Embedding: `text-embedding-3-small` with client type `openai-completions` (OpenAI) or `nomic-embed-text` with client type `openai-completions` (Ollama) ## Step 4: Edit or Delete diff --git a/internal/conversation/flow/resolver.go b/internal/conversation/flow/resolver.go index 82f7967c..c35c6644 100644 --- a/internal/conversation/flow/resolver.go +++ b/internal/conversation/flow/resolver.go @@ -213,10 +213,8 @@ func (r *Resolver) resolve(ctx context.Context, req conversation.ChatRequest) (r if err != nil { return resolvedContext{}, err } - clientType, err := normalizeClientType(provider.ClientType) - if err != nil { - return resolvedContext{}, err - } + clientType := string(chatModel.ClientType) + maxCtx := coalescePositiveInt(req.MaxContextLoadTime, botSettings.MaxContextLoadTime, defaultMaxContextMinutes) maxTokens := botSettings.MaxContextTokens @@ -306,7 +304,7 @@ func (r *Resolver) Chat(ctx context.Context, req conversation.ChatRequest) (conv Messages: resp.Messages, Skills: resp.Skills, Model: rc.model.ModelID, - Provider: rc.provider.ClientType, + Provider: string(rc.model.ClientType), }, nil } @@ -1235,8 +1233,7 @@ func (r *Resolver) loadBotSettings(ctx context.Context, botID string) (settings. func normalizeClientType(clientType string) (string, error) { ct := strings.ToLower(strings.TrimSpace(clientType)) switch ct { - case "openai", "openai-compat", "anthropic", "google", - "azure", "bedrock", "mistral", "xai", "ollama", "dashscope": + case "openai-responses", "openai-completions", "anthropic-messages", "google-generative-ai": return ct, nil default: return "", fmt.Errorf("unsupported agent gateway client type: %s", clientType) diff --git a/internal/db/sqlc/models.go b/internal/db/sqlc/models.go index e3b214df..e15399c0 100644 --- a/internal/db/sqlc/models.go +++ b/internal/db/sqlc/models.go @@ -166,14 +166,13 @@ type LifecycleEvent struct { } type LlmProvider struct { - ID pgtype.UUID `json:"id"` - Name string `json:"name"` - ClientType string `json:"client_type"` - BaseUrl string `json:"base_url"` - ApiKey string `json:"api_key"` - Metadata []byte `json:"metadata"` - CreatedAt pgtype.Timestamptz `json:"created_at"` - UpdatedAt pgtype.Timestamptz `json:"updated_at"` + ID pgtype.UUID `json:"id"` + Name string `json:"name"` + BaseUrl string `json:"base_url"` + ApiKey string `json:"api_key"` + Metadata []byte `json:"metadata"` + CreatedAt pgtype.Timestamptz `json:"created_at"` + UpdatedAt pgtype.Timestamptz `json:"updated_at"` } type McpConnection struct { @@ -209,6 +208,7 @@ type Model struct { ModelID string `json:"model_id"` Name pgtype.Text `json:"name"` LlmProviderID pgtype.UUID `json:"llm_provider_id"` + ClientType pgtype.Text `json:"client_type"` Dimensions pgtype.Int4 `json:"dimensions"` InputModalities []string `json:"input_modalities"` Type string `json:"type"` diff --git a/internal/db/sqlc/models.sql.go b/internal/db/sqlc/models.sql.go index e6dca657..4c919ce6 100644 --- a/internal/db/sqlc/models.sql.go +++ b/internal/db/sqlc/models.sql.go @@ -22,17 +22,6 @@ func (q *Queries) CountLlmProviders(ctx context.Context) (int64, error) { return count, err } -const countLlmProvidersByClientType = `-- name: CountLlmProvidersByClientType :one -SELECT COUNT(*) FROM llm_providers WHERE client_type = $1 -` - -func (q *Queries) CountLlmProvidersByClientType(ctx context.Context, clientType string) (int64, error) { - row := q.db.QueryRow(ctx, countLlmProvidersByClientType, clientType) - var count int64 - err := row.Scan(&count) - return count, err -} - const countModels = `-- name: CountModels :one SELECT COUNT(*) FROM models ` @@ -56,29 +45,26 @@ func (q *Queries) CountModelsByType(ctx context.Context, type_ string) (int64, e } const createLlmProvider = `-- name: CreateLlmProvider :one -INSERT INTO llm_providers (name, client_type, base_url, api_key, metadata) +INSERT INTO llm_providers (name, base_url, api_key, metadata) VALUES ( $1, $2, $3, - $4, - $5 + $4 ) -RETURNING id, name, client_type, base_url, api_key, metadata, created_at, updated_at +RETURNING id, name, base_url, api_key, metadata, created_at, updated_at ` type CreateLlmProviderParams struct { - Name string `json:"name"` - ClientType string `json:"client_type"` - BaseUrl string `json:"base_url"` - ApiKey string `json:"api_key"` - Metadata []byte `json:"metadata"` + Name string `json:"name"` + BaseUrl string `json:"base_url"` + ApiKey string `json:"api_key"` + Metadata []byte `json:"metadata"` } func (q *Queries) CreateLlmProvider(ctx context.Context, arg CreateLlmProviderParams) (LlmProvider, error) { row := q.db.QueryRow(ctx, createLlmProvider, arg.Name, - arg.ClientType, arg.BaseUrl, arg.ApiKey, arg.Metadata, @@ -87,7 +73,6 @@ func (q *Queries) CreateLlmProvider(ctx context.Context, arg CreateLlmProviderPa err := row.Scan( &i.ID, &i.Name, - &i.ClientType, &i.BaseUrl, &i.ApiKey, &i.Metadata, @@ -98,22 +83,24 @@ func (q *Queries) CreateLlmProvider(ctx context.Context, arg CreateLlmProviderPa } const createModel = `-- name: CreateModel :one -INSERT INTO models (model_id, name, llm_provider_id, dimensions, input_modalities, type) +INSERT INTO models (model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type) VALUES ( $1, $2, $3, $4, $5, - $6 + $6, + $7 ) -RETURNING id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at +RETURNING id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at ` type CreateModelParams struct { ModelID string `json:"model_id"` Name pgtype.Text `json:"name"` LlmProviderID pgtype.UUID `json:"llm_provider_id"` + ClientType pgtype.Text `json:"client_type"` Dimensions pgtype.Int4 `json:"dimensions"` InputModalities []string `json:"input_modalities"` Type string `json:"type"` @@ -124,6 +111,7 @@ func (q *Queries) CreateModel(ctx context.Context, arg CreateModelParams) (Model arg.ModelID, arg.Name, arg.LlmProviderID, + arg.ClientType, arg.Dimensions, arg.InputModalities, arg.Type, @@ -134,6 +122,7 @@ func (q *Queries) CreateModel(ctx context.Context, arg CreateModelParams) (Model &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -209,7 +198,7 @@ func (q *Queries) DeleteModelByModelID(ctx context.Context, modelID string) erro } const getLlmProviderByID = `-- name: GetLlmProviderByID :one -SELECT id, name, client_type, base_url, api_key, metadata, created_at, updated_at FROM llm_providers WHERE id = $1 +SELECT id, name, base_url, api_key, metadata, created_at, updated_at FROM llm_providers WHERE id = $1 ` func (q *Queries) GetLlmProviderByID(ctx context.Context, id pgtype.UUID) (LlmProvider, error) { @@ -218,7 +207,6 @@ func (q *Queries) GetLlmProviderByID(ctx context.Context, id pgtype.UUID) (LlmPr err := row.Scan( &i.ID, &i.Name, - &i.ClientType, &i.BaseUrl, &i.ApiKey, &i.Metadata, @@ -229,7 +217,7 @@ func (q *Queries) GetLlmProviderByID(ctx context.Context, id pgtype.UUID) (LlmPr } const getLlmProviderByName = `-- name: GetLlmProviderByName :one -SELECT id, name, client_type, base_url, api_key, metadata, created_at, updated_at FROM llm_providers WHERE name = $1 +SELECT id, name, base_url, api_key, metadata, created_at, updated_at FROM llm_providers WHERE name = $1 ` func (q *Queries) GetLlmProviderByName(ctx context.Context, name string) (LlmProvider, error) { @@ -238,7 +226,6 @@ func (q *Queries) GetLlmProviderByName(ctx context.Context, name string) (LlmPro err := row.Scan( &i.ID, &i.Name, - &i.ClientType, &i.BaseUrl, &i.ApiKey, &i.Metadata, @@ -249,7 +236,7 @@ func (q *Queries) GetLlmProviderByName(ctx context.Context, name string) (LlmPro } const getModelByID = `-- name: GetModelByID :one -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE id = $1 +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE id = $1 ` func (q *Queries) GetModelByID(ctx context.Context, id pgtype.UUID) (Model, error) { @@ -260,6 +247,7 @@ func (q *Queries) GetModelByID(ctx context.Context, id pgtype.UUID) (Model, erro &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -270,7 +258,7 @@ func (q *Queries) GetModelByID(ctx context.Context, id pgtype.UUID) (Model, erro } const getModelByModelID = `-- name: GetModelByModelID :one -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE model_id = $1 +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE model_id = $1 ` func (q *Queries) GetModelByModelID(ctx context.Context, modelID string) (Model, error) { @@ -281,6 +269,7 @@ func (q *Queries) GetModelByModelID(ctx context.Context, modelID string) (Model, &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -291,7 +280,7 @@ func (q *Queries) GetModelByModelID(ctx context.Context, modelID string) (Model, } const listLlmProviders = `-- name: ListLlmProviders :many -SELECT id, name, client_type, base_url, api_key, metadata, created_at, updated_at FROM llm_providers +SELECT id, name, base_url, api_key, metadata, created_at, updated_at FROM llm_providers ORDER BY created_at DESC ` @@ -307,42 +296,6 @@ func (q *Queries) ListLlmProviders(ctx context.Context) ([]LlmProvider, error) { if err := rows.Scan( &i.ID, &i.Name, - &i.ClientType, - &i.BaseUrl, - &i.ApiKey, - &i.Metadata, - &i.CreatedAt, - &i.UpdatedAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const listLlmProvidersByClientType = `-- name: ListLlmProvidersByClientType :many -SELECT id, name, client_type, base_url, api_key, metadata, created_at, updated_at FROM llm_providers -WHERE client_type = $1 -ORDER BY created_at DESC -` - -func (q *Queries) ListLlmProvidersByClientType(ctx context.Context, clientType string) ([]LlmProvider, error) { - rows, err := q.db.Query(ctx, listLlmProvidersByClientType, clientType) - if err != nil { - return nil, err - } - defer rows.Close() - var items []LlmProvider - for rows.Next() { - var i LlmProvider - if err := rows.Scan( - &i.ID, - &i.Name, - &i.ClientType, &i.BaseUrl, &i.ApiKey, &i.Metadata, @@ -394,7 +347,7 @@ func (q *Queries) ListModelVariantsByModelUUID(ctx context.Context, modelUuid pg } const listModels = `-- name: ListModels :many -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models ORDER BY created_at DESC ` @@ -412,6 +365,7 @@ func (q *Queries) ListModels(ctx context.Context) ([]Model, error) { &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -429,13 +383,12 @@ func (q *Queries) ListModels(ctx context.Context) ([]Model, error) { } const listModelsByClientType = `-- name: ListModelsByClientType :many -SELECT m.id, m.model_id, m.name, m.llm_provider_id, m.dimensions, m.input_modalities, m.type, m.created_at, m.updated_at FROM models AS m -JOIN llm_providers AS p ON p.id = m.llm_provider_id -WHERE p.client_type = $1 -ORDER BY m.created_at DESC +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models +WHERE client_type = $1 +ORDER BY created_at DESC ` -func (q *Queries) ListModelsByClientType(ctx context.Context, clientType string) ([]Model, error) { +func (q *Queries) ListModelsByClientType(ctx context.Context, clientType pgtype.Text) ([]Model, error) { rows, err := q.db.Query(ctx, listModelsByClientType, clientType) if err != nil { return nil, err @@ -449,6 +402,7 @@ func (q *Queries) ListModelsByClientType(ctx context.Context, clientType string) &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -466,7 +420,7 @@ func (q *Queries) ListModelsByClientType(ctx context.Context, clientType string) } const listModelsByProviderID = `-- name: ListModelsByProviderID :many -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE llm_provider_id = $1 ORDER BY created_at DESC ` @@ -485,6 +439,7 @@ func (q *Queries) ListModelsByProviderID(ctx context.Context, llmProviderID pgty &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -502,7 +457,7 @@ func (q *Queries) ListModelsByProviderID(ctx context.Context, llmProviderID pgty } const listModelsByProviderIDAndType = `-- name: ListModelsByProviderIDAndType :many -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE llm_provider_id = $1 AND type = $2 ORDER BY created_at DESC @@ -527,6 +482,7 @@ func (q *Queries) ListModelsByProviderIDAndType(ctx context.Context, arg ListMod &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -544,7 +500,7 @@ func (q *Queries) ListModelsByProviderIDAndType(ctx context.Context, arg ListMod } const listModelsByType = `-- name: ListModelsByType :many -SELECT id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at FROM models +SELECT id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at FROM models WHERE type = $1 ORDER BY created_at DESC ` @@ -563,6 +519,7 @@ func (q *Queries) ListModelsByType(ctx context.Context, type_ string) ([]Model, &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -583,28 +540,25 @@ const updateLlmProvider = `-- name: UpdateLlmProvider :one UPDATE llm_providers SET name = $1, - client_type = $2, - base_url = $3, - api_key = $4, - metadata = $5, + base_url = $2, + api_key = $3, + metadata = $4, updated_at = now() -WHERE id = $6 -RETURNING id, name, client_type, base_url, api_key, metadata, created_at, updated_at +WHERE id = $5 +RETURNING id, name, base_url, api_key, metadata, created_at, updated_at ` type UpdateLlmProviderParams struct { - Name string `json:"name"` - ClientType string `json:"client_type"` - BaseUrl string `json:"base_url"` - ApiKey string `json:"api_key"` - Metadata []byte `json:"metadata"` - ID pgtype.UUID `json:"id"` + Name string `json:"name"` + BaseUrl string `json:"base_url"` + ApiKey string `json:"api_key"` + Metadata []byte `json:"metadata"` + ID pgtype.UUID `json:"id"` } func (q *Queries) UpdateLlmProvider(ctx context.Context, arg UpdateLlmProviderParams) (LlmProvider, error) { row := q.db.QueryRow(ctx, updateLlmProvider, arg.Name, - arg.ClientType, arg.BaseUrl, arg.ApiKey, arg.Metadata, @@ -614,7 +568,6 @@ func (q *Queries) UpdateLlmProvider(ctx context.Context, arg UpdateLlmProviderPa err := row.Scan( &i.ID, &i.Name, - &i.ClientType, &i.BaseUrl, &i.ApiKey, &i.Metadata, @@ -629,17 +582,19 @@ UPDATE models SET name = $1, llm_provider_id = $2, - dimensions = $3, - input_modalities = $4, - type = $5, + client_type = $3, + dimensions = $4, + input_modalities = $5, + type = $6, updated_at = now() -WHERE id = $6 -RETURNING id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at +WHERE id = $7 +RETURNING id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at ` type UpdateModelParams struct { Name pgtype.Text `json:"name"` LlmProviderID pgtype.UUID `json:"llm_provider_id"` + ClientType pgtype.Text `json:"client_type"` Dimensions pgtype.Int4 `json:"dimensions"` InputModalities []string `json:"input_modalities"` Type string `json:"type"` @@ -650,6 +605,7 @@ func (q *Queries) UpdateModel(ctx context.Context, arg UpdateModelParams) (Model row := q.db.QueryRow(ctx, updateModel, arg.Name, arg.LlmProviderID, + arg.ClientType, arg.Dimensions, arg.InputModalities, arg.Type, @@ -661,6 +617,7 @@ func (q *Queries) UpdateModel(ctx context.Context, arg UpdateModelParams) (Model &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, @@ -676,18 +633,20 @@ SET model_id = $1, name = $2, llm_provider_id = $3, - dimensions = $4, - input_modalities = $5, - type = $6, + client_type = $4, + dimensions = $5, + input_modalities = $6, + type = $7, updated_at = now() -WHERE model_id = $7 -RETURNING id, model_id, name, llm_provider_id, dimensions, input_modalities, type, created_at, updated_at +WHERE model_id = $8 +RETURNING id, model_id, name, llm_provider_id, client_type, dimensions, input_modalities, type, created_at, updated_at ` type UpdateModelByModelIDParams struct { NewModelID string `json:"new_model_id"` Name pgtype.Text `json:"name"` LlmProviderID pgtype.UUID `json:"llm_provider_id"` + ClientType pgtype.Text `json:"client_type"` Dimensions pgtype.Int4 `json:"dimensions"` InputModalities []string `json:"input_modalities"` Type string `json:"type"` @@ -699,6 +658,7 @@ func (q *Queries) UpdateModelByModelID(ctx context.Context, arg UpdateModelByMod arg.NewModelID, arg.Name, arg.LlmProviderID, + arg.ClientType, arg.Dimensions, arg.InputModalities, arg.Type, @@ -710,6 +670,7 @@ func (q *Queries) UpdateModelByModelID(ctx context.Context, arg UpdateModelByMod &i.ModelID, &i.Name, &i.LlmProviderID, + &i.ClientType, &i.Dimensions, &i.InputModalities, &i.Type, diff --git a/internal/embeddings/resolver.go b/internal/embeddings/resolver.go index d9393638..fa82e49c 100644 --- a/internal/embeddings/resolver.go +++ b/internal/embeddings/resolver.go @@ -17,10 +17,6 @@ import ( const ( TypeText = "text" TypeMultimodal = "multimodal" - - ProviderOpenAI = "openai" - ProviderBedrock = "bedrock" - ProviderDashScope = "dashscope" ) type Request struct { @@ -81,16 +77,10 @@ func (r *Resolver) Embed(ctx context.Context, req Request) (Result, error) { } switch req.Type { case TypeText: - if req.Provider != "" && req.Provider != ProviderOpenAI { - return Result{}, errors.New("invalid provider for text embeddings") - } if req.Input.Text == "" { return Result{}, errors.New("text input is required") } case TypeMultimodal: - if req.Provider != "" && req.Provider != ProviderBedrock && req.Provider != ProviderDashScope { - return Result{}, errors.New("invalid provider for multimodal embeddings") - } if req.Input.Text == "" && req.Input.ImageURL == "" && req.Input.VideoURL == "" { return Result{}, errors.New("multimodal input is required") } @@ -109,7 +99,9 @@ func (r *Resolver) Embed(ctx context.Context, req Request) (Result, error) { req.Model = selected.ModelID req.Dimensions = selected.Dimensions - req.Provider = strings.ToLower(strings.TrimSpace(provider.ClientType)) + if selected.ClientType != "" { + req.Provider = string(selected.ClientType) + } if req.Model == "" { return Result{}, errors.New("embedding model id not configured") } @@ -122,11 +114,9 @@ func (r *Resolver) Embed(ctx context.Context, req Request) (Result, error) { timeout = 10 * time.Second } + // OpenAI-compatible embeddings work for both openai-responses and openai-completions switch req.Type { case TypeText: - if req.Provider != ProviderOpenAI { - return Result{}, errors.New("provider not implemented") - } embedder, err := NewOpenAIEmbedder(r.logger, provider.ApiKey, provider.BaseUrl, req.Model, req.Dimensions, timeout) if err != nil { return Result{}, err @@ -143,29 +133,7 @@ func (r *Resolver) Embed(ctx context.Context, req Request) (Result, error) { Embedding: vector, }, nil case TypeMultimodal: - if req.Provider == ProviderDashScope { - if strings.TrimSpace(provider.ApiKey) == "" { - return Result{}, errors.New("dashscope api key is required") - } - dashscope := NewDashScopeEmbedder(r.logger, provider.ApiKey, provider.BaseUrl, req.Model, timeout) - vector, usage, err := dashscope.Embed(ctx, req.Input.Text, req.Input.ImageURL, req.Input.VideoURL) - if err != nil { - return Result{}, err - } - return Result{ - Type: req.Type, - Provider: req.Provider, - Model: req.Model, - Dimensions: req.Dimensions, - Embedding: vector, - Usage: Usage{ - InputTokens: usage.InputTokens, - ImageTokens: usage.ImageTokens, - Duration: usage.Duration, - }, - }, nil - } - return Result{}, errors.New("provider not implemented") + return Result{}, errors.New("multimodal embeddings not supported for current provider types") default: return Result{}, errors.New("invalid embeddings type") } diff --git a/internal/handlers/models.go b/internal/handlers/models.go index 58fb3a77..51a6f402 100644 --- a/internal/handlers/models.go +++ b/internal/handlers/models.go @@ -62,7 +62,7 @@ func (h *ModelsHandler) Create(c echo.Context) error { // @Description Get a list of all configured models, optionally filtered by type or client type // @Tags models // @Param type query string false "Model type (chat, embedding)" -// @Param client_type query string false "Client type (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)" +// @Param client_type query string false "Client type (openai-responses, openai-completions, anthropic-messages, google-generative-ai)" // @Success 200 {array} models.GetResponse // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse diff --git a/internal/handlers/providers.go b/internal/handlers/providers.go index 22864ac1..9e6473f4 100644 --- a/internal/handlers/providers.go +++ b/internal/handlers/providers.go @@ -58,9 +58,6 @@ func (h *ProvidersHandler) Create(c echo.Context) error { if req.Name == "" { return echo.NewHTTPError(http.StatusBadRequest, "name is required") } - if req.ClientType == "" { - return echo.NewHTTPError(http.StatusBadRequest, "client_type is required") - } if req.BaseURL == "" { return echo.NewHTTPError(http.StatusBadRequest, "base_url is required") } @@ -75,27 +72,15 @@ func (h *ProvidersHandler) Create(c echo.Context) error { // List godoc // @Summary List all LLM providers -// @Description Get a list of all configured LLM providers, optionally filtered by client type +// @Description Get a list of all configured LLM providers // @Tags providers // @Accept json // @Produce json -// @Param client_type query string false "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)" // @Success 200 {array} providers.GetResponse -// @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /providers [get] func (h *ProvidersHandler) List(c echo.Context) error { - clientType := c.QueryParam("client_type") - - var resp []providers.GetResponse - var err error - - if clientType != "" { - resp, err = h.service.ListByClientType(c.Request().Context(), providers.ClientType(clientType)) - } else { - resp, err = h.service.List(c.Request().Context()) - } - + resp, err := h.service.List(c.Request().Context()) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } @@ -252,27 +237,15 @@ func (h *ProvidersHandler) Delete(c echo.Context) error { // Count godoc // @Summary Count providers -// @Description Get the total count of providers, optionally filtered by client type +// @Description Get the total count of providers // @Tags providers // @Accept json // @Produce json -// @Param client_type query string false "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)" // @Success 200 {object} providers.CountResponse -// @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /providers/count [get] func (h *ProvidersHandler) Count(c echo.Context) error { - clientType := c.QueryParam("client_type") - - var count int64 - var err error - - if clientType != "" { - count, err = h.service.CountByClientType(c.Request().Context(), providers.ClientType(clientType)) - } else { - count, err = h.service.Count(c.Request().Context()) - } - + count, err := h.service.Count(c.Request().Context()) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) } diff --git a/internal/models/models.go b/internal/models/models.go index 7ac5b27f..007f46e8 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -49,6 +49,9 @@ func (s *Service) Create(ctx context.Context, req AddRequest) (AddResponse, erro InputModalities: inputMod, Type: string(model.Type), } + if model.ClientType != "" { + params.ClientType = pgtype.Text{String: string(model.ClientType), Valid: true} + } // Handle optional name field if model.Name != "" { @@ -140,7 +143,7 @@ func (s *Service) ListByClientType(ctx context.Context, clientType ClientType) ( return nil, fmt.Errorf("invalid client type: %s", clientType) } - dbModels, err := s.queries.ListModelsByClientType(ctx, string(clientType)) + dbModels, err := s.queries.ListModelsByClientType(ctx, pgtype.Text{String: string(clientType), Valid: true}) if err != nil { return nil, fmt.Errorf("failed to list models by client type: %w", err) } @@ -207,6 +210,9 @@ func (s *Service) UpdateByID(ctx context.Context, id string, req UpdateRequest) InputModalities: inputMod, Type: string(model.Type), } + if model.ClientType != "" { + params.ClientType = pgtype.Text{String: string(model.ClientType), Valid: true} + } llmProviderID, err := db.ParseUUID(model.LlmProviderID) if err != nil { @@ -251,6 +257,9 @@ func (s *Service) UpdateByModelID(ctx context.Context, modelID string, req Updat InputModalities: inputMod, Type: string(model.Type), } + if model.ClientType != "" { + params.ClientType = pgtype.Text{String: string(model.ClientType), Valid: true} + } llmProviderID, err := db.ParseUUID(model.LlmProviderID) if err != nil { @@ -333,6 +342,9 @@ func convertToGetResponse(dbModel sqlc.Model) GetResponse { Type: ModelType(dbModel.Type), }, } + if dbModel.ClientType.Valid { + resp.Model.ClientType = ClientType(dbModel.ClientType.String) + } if resp.Model.Type == ModelTypeChat { resp.Model.InputModalities = normalizeModalities(dbModel.InputModalities, []string{ModelInputText}) } @@ -370,16 +382,10 @@ func normalizeModalities(modalities []string, fallback []string) []string { func isValidClientType(clientType ClientType) bool { switch clientType { - case ClientTypeOpenAI, - ClientTypeOpenAICompat, - ClientTypeAnthropic, - ClientTypeGoogle, - ClientTypeAzure, - ClientTypeBedrock, - ClientTypeMistral, - ClientTypeXAI, - ClientTypeOllama, - ClientTypeDashscope: + case ClientTypeOpenAIResponses, + ClientTypeOpenAICompletions, + ClientTypeAnthropicMessages, + ClientTypeGoogleGenerativeAI: return true default: return false diff --git a/internal/models/models_test.go b/internal/models/models_test.go index 762ad822..426696e8 100644 --- a/internal/models/models_test.go +++ b/internal/models/models_test.go @@ -110,6 +110,7 @@ func TestModel_Validate(t *testing.T) { ModelID: "gpt-4", Name: "GPT-4", LlmProviderID: "11111111-1111-1111-1111-111111111111", + ClientType: models.ClientTypeOpenAIResponses, Type: models.ModelTypeChat, }, wantErr: false, @@ -120,11 +121,33 @@ func TestModel_Validate(t *testing.T) { ModelID: "gpt-4o", Name: "GPT-4o", LlmProviderID: "11111111-1111-1111-1111-111111111111", + ClientType: models.ClientTypeOpenAIResponses, InputModalities: []string{"text", "image", "audio"}, Type: models.ModelTypeChat, }, wantErr: false, }, + { + name: "chat model missing client_type", + model: models.Model{ + ModelID: "gpt-4", + Name: "GPT-4", + LlmProviderID: "11111111-1111-1111-1111-111111111111", + Type: models.ModelTypeChat, + }, + wantErr: true, + }, + { + name: "embedding model without client_type is valid", + model: models.Model{ + ModelID: "text-embedding-3-small", + Name: "Embedding", + LlmProviderID: "11111111-1111-1111-1111-111111111111", + Type: models.ModelTypeEmbedding, + Dimensions: 1536, + }, + wantErr: false, + }, { name: "valid embedding model", model: models.Model{ @@ -185,6 +208,7 @@ func TestModel_Validate(t *testing.T) { model: models.Model{ ModelID: "gpt-4", LlmProviderID: "11111111-1111-1111-1111-111111111111", + ClientType: models.ClientTypeOpenAIResponses, Type: models.ModelTypeChat, InputModalities: []string{"text", "smell"}, }, @@ -262,15 +286,9 @@ func TestModelTypes(t *testing.T) { }) t.Run("ClientType constants", func(t *testing.T) { - assert.Equal(t, models.ClientType("openai"), models.ClientTypeOpenAI) - assert.Equal(t, models.ClientType("openai-compat"), models.ClientTypeOpenAICompat) - assert.Equal(t, models.ClientType("anthropic"), models.ClientTypeAnthropic) - assert.Equal(t, models.ClientType("google"), models.ClientTypeGoogle) - assert.Equal(t, models.ClientType("azure"), models.ClientTypeAzure) - assert.Equal(t, models.ClientType("bedrock"), models.ClientTypeBedrock) - assert.Equal(t, models.ClientType("mistral"), models.ClientTypeMistral) - assert.Equal(t, models.ClientType("xai"), models.ClientTypeXAI) - assert.Equal(t, models.ClientType("ollama"), models.ClientTypeOllama) - assert.Equal(t, models.ClientType("dashscope"), models.ClientTypeDashscope) + assert.Equal(t, models.ClientType("openai-responses"), models.ClientTypeOpenAIResponses) + assert.Equal(t, models.ClientType("openai-completions"), models.ClientTypeOpenAICompletions) + assert.Equal(t, models.ClientType("anthropic-messages"), models.ClientTypeAnthropicMessages) + assert.Equal(t, models.ClientType("google-generative-ai"), models.ClientTypeGoogleGenerativeAI) }) } diff --git a/internal/models/types.go b/internal/models/types.go index afa024ca..984a3cde 100644 --- a/internal/models/types.go +++ b/internal/models/types.go @@ -25,25 +25,20 @@ const ( type ClientType string const ( - ClientTypeOpenAI ClientType = "openai" - ClientTypeOpenAICompat ClientType = "openai-compat" - ClientTypeAnthropic ClientType = "anthropic" - ClientTypeGoogle ClientType = "google" - ClientTypeAzure ClientType = "azure" - ClientTypeBedrock ClientType = "bedrock" - ClientTypeMistral ClientType = "mistral" - ClientTypeXAI ClientType = "xai" - ClientTypeOllama ClientType = "ollama" - ClientTypeDashscope ClientType = "dashscope" + ClientTypeOpenAIResponses ClientType = "openai-responses" + ClientTypeOpenAICompletions ClientType = "openai-completions" + ClientTypeAnthropicMessages ClientType = "anthropic-messages" + ClientTypeGoogleGenerativeAI ClientType = "google-generative-ai" ) type Model struct { - ModelID string `json:"model_id"` - Name string `json:"name"` - LlmProviderID string `json:"llm_provider_id"` - InputModalities []string `json:"input_modalities,omitempty"` - Type ModelType `json:"type"` - Dimensions int `json:"dimensions"` + ModelID string `json:"model_id"` + Name string `json:"name"` + LlmProviderID string `json:"llm_provider_id"` + ClientType ClientType `json:"client_type,omitempty"` + InputModalities []string `json:"input_modalities,omitempty"` + Type ModelType `json:"type"` + Dimensions int `json:"dimensions"` } // validInputModalities is the set of recognised input modality tokens. @@ -65,10 +60,17 @@ func (m *Model) Validate() error { if m.Type != ModelTypeChat && m.Type != ModelTypeEmbedding { return errors.New("invalid model type") } + if m.Type == ModelTypeChat { + if m.ClientType == "" { + return errors.New("client_type is required for chat models") + } + if !isValidClientType(m.ClientType) { + return fmt.Errorf("invalid client_type: %s", m.ClientType) + } + } if m.Type == ModelTypeEmbedding && m.Dimensions <= 0 { return errors.New("dimensions must be greater than 0") } - // Input modalities only apply to chat models. if m.Type == ModelTypeChat { for _, mod := range m.InputModalities { if _, ok := validInputModalities[mod]; !ok { diff --git a/internal/providers/service.go b/internal/providers/service.go index b1a205f0..5038f2a9 100644 --- a/internal/providers/service.go +++ b/internal/providers/service.go @@ -27,11 +27,6 @@ func NewService(log *slog.Logger, queries *sqlc.Queries) *Service { // Create creates a new LLM provider func (s *Service) Create(ctx context.Context, req CreateRequest) (GetResponse, error) { - // Validate client type - if !isValidClientType(req.ClientType) { - return GetResponse{}, fmt.Errorf("invalid client_type: %s", req.ClientType) - } - // Marshal metadata metadataJSON, err := json.Marshal(req.Metadata) if err != nil { @@ -40,11 +35,10 @@ func (s *Service) Create(ctx context.Context, req CreateRequest) (GetResponse, e // Create provider provider, err := s.queries.CreateLlmProvider(ctx, sqlc.CreateLlmProviderParams{ - Name: req.Name, - ClientType: string(req.ClientType), - BaseUrl: req.BaseURL, - ApiKey: req.APIKey, - Metadata: metadataJSON, + Name: req.Name, + BaseUrl: req.BaseURL, + ApiKey: req.APIKey, + Metadata: metadataJSON, }) if err != nil { return GetResponse{}, fmt.Errorf("create provider: %w", err) @@ -92,24 +86,6 @@ func (s *Service) List(ctx context.Context) ([]GetResponse, error) { return results, nil } -// ListByClientType retrieves providers by client type -func (s *Service) ListByClientType(ctx context.Context, clientType ClientType) ([]GetResponse, error) { - if !isValidClientType(clientType) { - return nil, fmt.Errorf("invalid client_type: %s", clientType) - } - - providers, err := s.queries.ListLlmProvidersByClientType(ctx, string(clientType)) - if err != nil { - return nil, fmt.Errorf("list providers by client type: %w", err) - } - - results := make([]GetResponse, 0, len(providers)) - for _, p := range providers { - results = append(results, s.toGetResponse(p)) - } - return results, nil -} - // Update updates an existing provider func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (GetResponse, error) { providerID, err := db.ParseUUID(id) @@ -129,14 +105,6 @@ func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (Get name = *req.Name } - clientType := existing.ClientType - if req.ClientType != nil { - if !isValidClientType(*req.ClientType) { - return GetResponse{}, fmt.Errorf("invalid client_type: %s", *req.ClientType) - } - clientType = string(*req.ClientType) - } - baseURL := existing.BaseUrl if req.BaseURL != nil { baseURL = *req.BaseURL @@ -155,12 +123,11 @@ func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (Get // Update provider updated, err := s.queries.UpdateLlmProvider(ctx, sqlc.UpdateLlmProviderParams{ - ID: providerID, - Name: name, - ClientType: clientType, - BaseUrl: baseURL, - ApiKey: apiKey, - Metadata: metadata, + ID: providerID, + Name: name, + BaseUrl: baseURL, + ApiKey: apiKey, + Metadata: metadata, }) if err != nil { return GetResponse{}, fmt.Errorf("update provider: %w", err) @@ -191,19 +158,6 @@ func (s *Service) Count(ctx context.Context) (int64, error) { return count, nil } -// CountByClientType returns the count of providers by client type -func (s *Service) CountByClientType(ctx context.Context, clientType ClientType) (int64, error) { - if !isValidClientType(clientType) { - return 0, fmt.Errorf("invalid client_type: %s", clientType) - } - - count, err := s.queries.CountLlmProvidersByClientType(ctx, string(clientType)) - if err != nil { - return 0, fmt.Errorf("count providers by client type: %w", err) - } - return count, nil -} - // toGetResponse converts a database provider to a response func (s *Service) toGetResponse(provider sqlc.LlmProvider) GetResponse { var metadata map[string]any @@ -217,26 +171,13 @@ func (s *Service) toGetResponse(provider sqlc.LlmProvider) GetResponse { maskedAPIKey := maskAPIKey(provider.ApiKey) return GetResponse{ - ID: provider.ID.String(), - Name: provider.Name, - ClientType: provider.ClientType, - BaseURL: provider.BaseUrl, - APIKey: maskedAPIKey, - Metadata: metadata, - CreatedAt: provider.CreatedAt.Time, - UpdatedAt: provider.UpdatedAt.Time, - } -} - -// isValidClientType checks if a client type is valid -func isValidClientType(clientType ClientType) bool { - switch clientType { - case ClientTypeOpenAI, ClientTypeOpenAICompat, ClientTypeAnthropic, ClientTypeGoogle, - ClientTypeAzure, ClientTypeBedrock, ClientTypeMistral, ClientTypeXAI, - ClientTypeOllama, ClientTypeDashscope: - return true - default: - return false + ID: provider.ID.String(), + Name: provider.Name, + BaseURL: provider.BaseUrl, + APIKey: maskedAPIKey, + Metadata: metadata, + CreatedAt: provider.CreatedAt.Time, + UpdatedAt: provider.UpdatedAt.Time, } } diff --git a/internal/providers/types.go b/internal/providers/types.go index 1af60fca..dcf7bf00 100644 --- a/internal/providers/types.go +++ b/internal/providers/types.go @@ -2,50 +2,31 @@ package providers import "time" -// ClientType represents the type of LLM provider client -type ClientType string - -const ( - ClientTypeOpenAI ClientType = "openai" - ClientTypeOpenAICompat ClientType = "openai-compat" - ClientTypeAnthropic ClientType = "anthropic" - ClientTypeGoogle ClientType = "google" - ClientTypeAzure ClientType = "azure" - ClientTypeBedrock ClientType = "bedrock" - ClientTypeMistral ClientType = "mistral" - ClientTypeXAI ClientType = "xai" - ClientTypeOllama ClientType = "ollama" - ClientTypeDashscope ClientType = "dashscope" -) - // CreateRequest represents a request to create a new LLM provider type CreateRequest struct { - Name string `json:"name" validate:"required"` - ClientType ClientType `json:"client_type" validate:"required"` - BaseURL string `json:"base_url" validate:"required,url"` - APIKey string `json:"api_key"` - Metadata map[string]any `json:"metadata,omitempty"` + Name string `json:"name" validate:"required"` + BaseURL string `json:"base_url" validate:"required,url"` + APIKey string `json:"api_key"` + Metadata map[string]any `json:"metadata,omitempty"` } // UpdateRequest represents a request to update an existing LLM provider type UpdateRequest struct { - Name *string `json:"name,omitempty"` - ClientType *ClientType `json:"client_type,omitempty"` - BaseURL *string `json:"base_url,omitempty"` - APIKey *string `json:"api_key,omitempty"` - Metadata map[string]any `json:"metadata,omitempty"` + Name *string `json:"name,omitempty"` + BaseURL *string `json:"base_url,omitempty"` + APIKey *string `json:"api_key,omitempty"` + Metadata map[string]any `json:"metadata,omitempty"` } // 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"` - 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"` + ID string `json:"id"` + Name string `json:"name"` + BaseURL string `json:"base_url"` + 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"` } // ListResponse represents the response for listing providers @@ -61,10 +42,9 @@ type CountResponse struct { // TestRequest represents a request to test provider connection type TestRequest struct { - ClientType ClientType `json:"client_type" validate:"required"` - BaseURL string `json:"base_url" validate:"required,url"` - APIKey string `json:"api_key"` - Model string `json:"model"` // optional test model + BaseURL string `json:"base_url" validate:"required,url"` + APIKey string `json:"api_key"` + Model string `json:"model"` // optional test model } // TestResponse represents the result of testing a provider diff --git a/packages/cli/src/cli/index.ts b/packages/cli/src/cli/index.ts index c79cb8ab..bf04381b 100755 --- a/packages/cli/src/cli/index.ts +++ b/packages/cli/src/cli/index.ts @@ -81,14 +81,13 @@ const ensureModelsReady = async () => { } const renderProvidersTable = (providers: ProvidersGetResponse[], models: ModelsGetResponse[]) => { - const rows: string[][] = [['Provider', 'Type', 'Base URL', 'Models']] + const rows: string[][] = [['Provider', 'Base URL', 'Models']] for (const provider of providers) { const providerModels = models .filter(m => getProviderId(m) === provider.id) .map(m => `${getModelId(m)} (${getModelType(m)})`) rows.push([ provider.name ?? '', - provider.client_type ?? '', provider.base_url ?? '', providerModels.join(', ') || '-', ]) @@ -259,21 +258,12 @@ provider .command('create') .description('Create provider') .option('--name ') - .option('--type ') .option('--base_url ') .option('--api_key ') .action(async (opts) => { ensureAuth() const questions = [] if (!opts.name) questions.push({ type: 'input', name: 'name', message: 'Provider name:' }) - if (!opts.type) { - questions.push({ - type: 'list', - name: 'client_type', - message: 'Client type:', - choices: ['openai', 'openai-compat', 'anthropic', 'google', 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope'], - }) - } if (!opts.base_url) questions.push({ type: 'input', name: 'base_url', message: 'Base URL:' }) if (!opts.api_key) questions.push({ type: 'password', name: 'api_key', message: 'API key:' }) const answers = questions.length ? await inquirer.prompt(questions) : {} @@ -282,7 +272,6 @@ provider await postProviders({ body: { name: opts.name ?? answers.name, - client_type: opts.type ?? answers.client_type, base_url: opts.base_url ?? answers.base_url, api_key: opts.api_key ?? answers.api_key, }, @@ -349,6 +338,7 @@ model .option('--model_id ') .option('--name ') .option('--provider ') + .option('--client_type ', 'Client type: openai-responses, openai-completions, anthropic-messages, google-generative-ai') .option('--type ') .option('--dimensions ') .option('--multimodal', 'Is multimodal') @@ -376,6 +366,16 @@ model const answers = questions.length ? await inquirer.prompt(questions) : {} const modelId = opts.model_id ?? answers.model_id const modelType = opts.type ?? answers.type + let clientType = opts.client_type + if (modelType === 'chat' && !clientType) { + const ctAnswer = await inquirer.prompt([{ + type: 'list', + name: 'client_type', + message: 'Client type:', + choices: ['openai-responses', 'openai-completions', 'anthropic-messages', 'google-generative-ai'], + }]) + clientType = ctAnswer.client_type + } let dimensions = opts.dimensions ? Number.parseInt(opts.dimensions, 10) : undefined if (modelType === 'embedding' && (!dimensions || Number.isNaN(dimensions))) { const dimAnswer = await inquirer.prompt([{ @@ -392,17 +392,18 @@ model const inputModalities = opts.multimodal ? ['text', 'image'] : ['text'] const spinner = ora('Creating model...').start() try { - await postModels({ - body: { - model_id: modelId, - name: opts.name ?? modelId, - llm_provider_id: provider.id, - input_modalities: inputModalities, - type: modelType, - dimensions, - }, - throwOnError: true, - }) + const body: Record = { + model_id: modelId, + name: opts.name ?? modelId, + llm_provider_id: provider.id, + input_modalities: inputModalities, + type: modelType, + dimensions, + } + if (modelType === 'chat' && clientType) { + body.client_type = clientType + } + await postModels({ body: body as any, throwOnError: true }) spinner.succeed('Model created') } catch (err: unknown) { spinner.fail(getErrorMessage(err) || 'Failed to create model') diff --git a/packages/cli/src/types/index.ts b/packages/cli/src/types/index.ts index e564c596..a214a340 100644 --- a/packages/cli/src/types/index.ts +++ b/packages/cli/src/types/index.ts @@ -12,7 +12,6 @@ export type { ChannelChannelIdentityBinding, ModelsGetResponse, ModelsModelType, - ProvidersClientType, ProvidersGetResponse, ScheduleListResponse, ScheduleSchedule, diff --git a/packages/sdk/src/@pinia/colada.gen.ts b/packages/sdk/src/@pinia/colada.gen.ts index f0e9912e..cb2e0c3a 100644 --- a/packages/sdk/src/@pinia/colada.gen.ts +++ b/packages/sdk/src/@pinia/colada.gen.ts @@ -1363,7 +1363,7 @@ export const getProvidersQueryKey = (options?: Options) => cre /** * List all LLM providers * - * Get a list of all configured LLM providers, optionally filtered by client type + * Get a list of all configured LLM providers */ export const getProvidersQuery = defineQueryOptions((options?: Options) => ({ key: getProvidersQueryKey(options), @@ -1398,7 +1398,7 @@ export const getProvidersCountQueryKey = (options?: Options) => ({ key: getProvidersCountQueryKey(options), diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 9b608be4..021dfd17 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts export { deleteBotsByBotIdContainer, deleteBotsByBotIdContainerSkills, deleteBotsByBotIdMcpById, deleteBotsByBotIdMemory, deleteBotsByBotIdMemoryById, deleteBotsByBotIdScheduleById, deleteBotsByBotIdSettings, deleteBotsByBotIdSubagentsById, deleteBotsById, deleteBotsByIdChannelByPlatform, deleteBotsByIdMembersByUserId, deleteModelsById, deleteModelsModelByModelId, deleteProvidersById, deleteSearchProvidersById, getBots, getBotsByBotIdContainer, getBotsByBotIdContainerSkills, getBotsByBotIdContainerSnapshots, getBotsByBotIdMcp, getBotsByBotIdMcpById, getBotsByBotIdMcpExport, getBotsByBotIdMemory, getBotsByBotIdMemoryUsage, getBotsByBotIdMessages, getBotsByBotIdSchedule, getBotsByBotIdScheduleById, getBotsByBotIdSettings, getBotsByBotIdSubagents, getBotsByBotIdSubagentsById, getBotsByBotIdSubagentsByIdContext, getBotsByBotIdSubagentsByIdSkills, getBotsById, getBotsByIdChannelByPlatform, getBotsByIdChecks, getBotsByIdMembers, getChannels, getChannelsByPlatform, getModels, getModelsById, getModelsCount, getModelsModelByModelId, getProviders, getProvidersById, getProvidersByIdModels, getProvidersCount, getProvidersNameByName, getSearchProviders, getSearchProvidersById, getSearchProvidersMeta, getUsers, getUsersById, getUsersMe, getUsersMeChannelsByPlatform, getUsersMeIdentities, type Options, patchBotsByIdChannelByPlatformStatus, postAuthLogin, postBots, postBotsByBotIdContainer, postBotsByBotIdContainerSkills, postBotsByBotIdContainerSnapshots, postBotsByBotIdContainerStart, postBotsByBotIdContainerStop, postBotsByBotIdMcp, postBotsByBotIdMcpOpsBatchDelete, postBotsByBotIdMcpStdio, postBotsByBotIdMcpStdioByConnectionId, postBotsByBotIdMemory, postBotsByBotIdMemoryCompact, postBotsByBotIdMemoryRebuild, postBotsByBotIdMemorySearch, postBotsByBotIdSchedule, postBotsByBotIdSettings, postBotsByBotIdSubagents, postBotsByBotIdSubagentsByIdSkills, postBotsByBotIdTools, postBotsByIdChannelByPlatformSend, postBotsByIdChannelByPlatformSendChat, postEmbeddings, postModels, postProviders, postSearchProviders, postUsers, putBotsByBotIdMcpById, putBotsByBotIdMcpImport, putBotsByBotIdScheduleById, putBotsByBotIdSettings, putBotsByBotIdSubagentsById, putBotsByBotIdSubagentsByIdContext, putBotsByBotIdSubagentsByIdSkills, putBotsById, putBotsByIdChannelByPlatform, putBotsByIdMembers, putBotsByIdOwner, putModelsById, putModelsModelByModelId, putProvidersById, putSearchProvidersById, putUsersById, putUsersByIdPassword, putUsersMe, putUsersMeChannelsByPlatform, putUsersMePassword } from './sdk.gen'; -export type { AccountsAccount, AccountsCreateAccountRequest, AccountsListAccountsResponse, AccountsResetPasswordRequest, AccountsUpdateAccountRequest, AccountsUpdatePasswordRequest, AccountsUpdateProfileRequest, BotsBot, BotsBotCheck, BotsBotMember, BotsCreateBotRequest, BotsListBotsResponse, BotsListChecksResponse, BotsListMembersResponse, BotsTransferBotRequest, BotsUpdateBotRequest, BotsUpsertMemberRequest, ChannelAction, ChannelAttachment, ChannelAttachmentType, ChannelChannelCapabilities, ChannelChannelConfig, ChannelChannelIdentityBinding, ChannelConfigSchema, ChannelFieldSchema, ChannelFieldType, ChannelMessage, ChannelMessageFormat, ChannelMessagePart, ChannelMessagePartType, ChannelMessageTextStyle, ChannelReplyRef, ChannelSendRequest, ChannelTargetHint, ChannelTargetSpec, ChannelThreadRef, ChannelUpdateChannelStatusRequest, ChannelUpsertChannelIdentityConfigRequest, ChannelUpsertConfigRequest, ClientOptions, DeleteBotsByBotIdContainerData, DeleteBotsByBotIdContainerError, DeleteBotsByBotIdContainerErrors, DeleteBotsByBotIdContainerResponses, DeleteBotsByBotIdContainerSkillsData, DeleteBotsByBotIdContainerSkillsError, DeleteBotsByBotIdContainerSkillsErrors, DeleteBotsByBotIdContainerSkillsResponse, DeleteBotsByBotIdContainerSkillsResponses, DeleteBotsByBotIdMcpByIdData, DeleteBotsByBotIdMcpByIdError, DeleteBotsByBotIdMcpByIdErrors, DeleteBotsByBotIdMcpByIdResponses, DeleteBotsByBotIdMemoryByIdData, DeleteBotsByBotIdMemoryByIdError, DeleteBotsByBotIdMemoryByIdErrors, DeleteBotsByBotIdMemoryByIdResponse, DeleteBotsByBotIdMemoryByIdResponses, DeleteBotsByBotIdMemoryData, DeleteBotsByBotIdMemoryError, DeleteBotsByBotIdMemoryErrors, DeleteBotsByBotIdMemoryResponse, DeleteBotsByBotIdMemoryResponses, DeleteBotsByBotIdScheduleByIdData, DeleteBotsByBotIdScheduleByIdError, DeleteBotsByBotIdScheduleByIdErrors, DeleteBotsByBotIdScheduleByIdResponses, DeleteBotsByBotIdSettingsData, DeleteBotsByBotIdSettingsError, DeleteBotsByBotIdSettingsErrors, DeleteBotsByBotIdSettingsResponses, DeleteBotsByBotIdSubagentsByIdData, DeleteBotsByBotIdSubagentsByIdError, DeleteBotsByBotIdSubagentsByIdErrors, DeleteBotsByBotIdSubagentsByIdResponses, DeleteBotsByIdChannelByPlatformData, DeleteBotsByIdChannelByPlatformError, DeleteBotsByIdChannelByPlatformErrors, DeleteBotsByIdChannelByPlatformResponses, DeleteBotsByIdData, DeleteBotsByIdError, DeleteBotsByIdErrors, DeleteBotsByIdMembersByUserIdData, DeleteBotsByIdMembersByUserIdError, DeleteBotsByIdMembersByUserIdErrors, DeleteBotsByIdMembersByUserIdResponses, DeleteBotsByIdResponse, DeleteBotsByIdResponses, DeleteModelsByIdData, DeleteModelsByIdError, DeleteModelsByIdErrors, DeleteModelsByIdResponses, DeleteModelsModelByModelIdData, DeleteModelsModelByModelIdError, DeleteModelsModelByModelIdErrors, DeleteModelsModelByModelIdResponses, DeleteProvidersByIdData, DeleteProvidersByIdError, DeleteProvidersByIdErrors, DeleteProvidersByIdResponses, DeleteSearchProvidersByIdData, DeleteSearchProvidersByIdError, DeleteSearchProvidersByIdErrors, DeleteSearchProvidersByIdResponses, GetBotsByBotIdContainerData, GetBotsByBotIdContainerError, GetBotsByBotIdContainerErrors, GetBotsByBotIdContainerResponse, GetBotsByBotIdContainerResponses, GetBotsByBotIdContainerSkillsData, GetBotsByBotIdContainerSkillsError, GetBotsByBotIdContainerSkillsErrors, GetBotsByBotIdContainerSkillsResponse, GetBotsByBotIdContainerSkillsResponses, GetBotsByBotIdContainerSnapshotsData, GetBotsByBotIdContainerSnapshotsResponse, GetBotsByBotIdContainerSnapshotsResponses, GetBotsByBotIdMcpByIdData, GetBotsByBotIdMcpByIdError, GetBotsByBotIdMcpByIdErrors, GetBotsByBotIdMcpByIdResponse, GetBotsByBotIdMcpByIdResponses, GetBotsByBotIdMcpData, GetBotsByBotIdMcpError, GetBotsByBotIdMcpErrors, GetBotsByBotIdMcpExportData, GetBotsByBotIdMcpExportError, GetBotsByBotIdMcpExportErrors, GetBotsByBotIdMcpExportResponse, GetBotsByBotIdMcpExportResponses, GetBotsByBotIdMcpResponse, GetBotsByBotIdMcpResponses, GetBotsByBotIdMemoryData, GetBotsByBotIdMemoryError, GetBotsByBotIdMemoryErrors, GetBotsByBotIdMemoryResponse, GetBotsByBotIdMemoryResponses, GetBotsByBotIdMemoryUsageData, GetBotsByBotIdMemoryUsageError, GetBotsByBotIdMemoryUsageErrors, GetBotsByBotIdMemoryUsageResponse, GetBotsByBotIdMemoryUsageResponses, GetBotsByBotIdMessagesData, GetBotsByBotIdMessagesError, GetBotsByBotIdMessagesErrors, GetBotsByBotIdMessagesResponse, GetBotsByBotIdMessagesResponses, 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, GetBotsByIdChecksData, GetBotsByIdChecksError, GetBotsByIdChecksErrors, GetBotsByIdChecksResponse, GetBotsByIdChecksResponses, 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, GetSearchProvidersByIdData, GetSearchProvidersByIdError, GetSearchProvidersByIdErrors, GetSearchProvidersByIdResponse, GetSearchProvidersByIdResponses, GetSearchProvidersData, GetSearchProvidersError, GetSearchProvidersErrors, GetSearchProvidersMetaData, GetSearchProvidersMetaResponse, GetSearchProvidersMetaResponses, GetSearchProvidersResponse, GetSearchProvidersResponses, GetUsersByIdData, GetUsersByIdError, GetUsersByIdErrors, GetUsersByIdResponse, GetUsersByIdResponses, GetUsersData, GetUsersError, GetUsersErrors, GetUsersMeChannelsByPlatformData, GetUsersMeChannelsByPlatformError, GetUsersMeChannelsByPlatformErrors, GetUsersMeChannelsByPlatformResponse, GetUsersMeChannelsByPlatformResponses, GetUsersMeData, GetUsersMeError, GetUsersMeErrors, GetUsersMeIdentitiesData, GetUsersMeIdentitiesError, GetUsersMeIdentitiesErrors, GetUsersMeIdentitiesResponse, GetUsersMeIdentitiesResponses, GetUsersMeResponse, GetUsersMeResponses, GetUsersResponse, GetUsersResponses, GithubComMemohaiMemohInternalMcpConnection, HandlersBatchDeleteRequest, HandlersChannelMeta, HandlersCreateContainerRequest, HandlersCreateContainerResponse, HandlersCreateSnapshotRequest, HandlersCreateSnapshotResponse, HandlersEmbeddingsInput, HandlersEmbeddingsRequest, HandlersEmbeddingsResponse, HandlersEmbeddingsUsage, HandlersErrorResponse, HandlersGetContainerResponse, HandlersListMyIdentitiesResponse, HandlersListSnapshotsResponse, HandlersLoginRequest, HandlersLoginResponse, HandlersMcpStdioRequest, HandlersMcpStdioResponse, HandlersMemoryAddPayload, HandlersMemoryCompactPayload, HandlersMemoryDeletePayload, HandlersMemorySearchPayload, HandlersSkillItem, HandlersSkillsDeleteRequest, HandlersSkillsOpResponse, HandlersSkillsResponse, HandlersSkillsUpsertRequest, HandlersSnapshotInfo, IdentitiesChannelIdentity, McpExportResponse, McpImportRequest, McpListResponse, McpMcpServerEntry, McpUpsertRequest, MemoryCdfPoint, MemoryCompactResult, MemoryDeleteResponse, MemoryMemoryItem, MemoryMessage, MemoryRebuildResult, MemorySearchResponse, MemoryTopKBucket, MemoryUsageResponse, MessageMessage, MessageMessageAsset, ModelsAddRequest, ModelsAddResponse, ModelsCountResponse, ModelsGetResponse, ModelsModelType, ModelsUpdateRequest, PatchBotsByIdChannelByPlatformStatusData, PatchBotsByIdChannelByPlatformStatusError, PatchBotsByIdChannelByPlatformStatusErrors, PatchBotsByIdChannelByPlatformStatusResponse, PatchBotsByIdChannelByPlatformStatusResponses, PostAuthLoginData, PostAuthLoginError, PostAuthLoginErrors, PostAuthLoginResponse, PostAuthLoginResponses, PostBotsByBotIdContainerData, PostBotsByBotIdContainerError, PostBotsByBotIdContainerErrors, PostBotsByBotIdContainerResponse, PostBotsByBotIdContainerResponses, PostBotsByBotIdContainerSkillsData, PostBotsByBotIdContainerSkillsError, PostBotsByBotIdContainerSkillsErrors, PostBotsByBotIdContainerSkillsResponse, PostBotsByBotIdContainerSkillsResponses, PostBotsByBotIdContainerSnapshotsData, PostBotsByBotIdContainerSnapshotsError, PostBotsByBotIdContainerSnapshotsErrors, PostBotsByBotIdContainerSnapshotsResponse, PostBotsByBotIdContainerSnapshotsResponses, PostBotsByBotIdContainerStartData, PostBotsByBotIdContainerStartError, PostBotsByBotIdContainerStartErrors, PostBotsByBotIdContainerStartResponse, PostBotsByBotIdContainerStartResponses, PostBotsByBotIdContainerStopData, PostBotsByBotIdContainerStopError, PostBotsByBotIdContainerStopErrors, PostBotsByBotIdContainerStopResponse, PostBotsByBotIdContainerStopResponses, PostBotsByBotIdMcpData, PostBotsByBotIdMcpError, PostBotsByBotIdMcpErrors, PostBotsByBotIdMcpOpsBatchDeleteData, PostBotsByBotIdMcpOpsBatchDeleteError, PostBotsByBotIdMcpOpsBatchDeleteErrors, PostBotsByBotIdMcpOpsBatchDeleteResponses, PostBotsByBotIdMcpResponse, PostBotsByBotIdMcpResponses, PostBotsByBotIdMcpStdioByConnectionIdData, PostBotsByBotIdMcpStdioByConnectionIdError, PostBotsByBotIdMcpStdioByConnectionIdErrors, PostBotsByBotIdMcpStdioByConnectionIdResponse, PostBotsByBotIdMcpStdioByConnectionIdResponses, PostBotsByBotIdMcpStdioData, PostBotsByBotIdMcpStdioError, PostBotsByBotIdMcpStdioErrors, PostBotsByBotIdMcpStdioResponse, PostBotsByBotIdMcpStdioResponses, PostBotsByBotIdMemoryCompactData, PostBotsByBotIdMemoryCompactError, PostBotsByBotIdMemoryCompactErrors, PostBotsByBotIdMemoryCompactResponse, PostBotsByBotIdMemoryCompactResponses, PostBotsByBotIdMemoryData, PostBotsByBotIdMemoryError, PostBotsByBotIdMemoryErrors, PostBotsByBotIdMemoryRebuildData, PostBotsByBotIdMemoryRebuildError, PostBotsByBotIdMemoryRebuildErrors, PostBotsByBotIdMemoryRebuildResponse, PostBotsByBotIdMemoryRebuildResponses, PostBotsByBotIdMemoryResponse, PostBotsByBotIdMemoryResponses, PostBotsByBotIdMemorySearchData, PostBotsByBotIdMemorySearchError, PostBotsByBotIdMemorySearchErrors, PostBotsByBotIdMemorySearchResponse, PostBotsByBotIdMemorySearchResponses, PostBotsByBotIdScheduleData, PostBotsByBotIdScheduleError, PostBotsByBotIdScheduleErrors, PostBotsByBotIdScheduleResponse, PostBotsByBotIdScheduleResponses, PostBotsByBotIdSettingsData, PostBotsByBotIdSettingsError, PostBotsByBotIdSettingsErrors, PostBotsByBotIdSettingsResponse, PostBotsByBotIdSettingsResponses, PostBotsByBotIdSubagentsByIdSkillsData, PostBotsByBotIdSubagentsByIdSkillsError, PostBotsByBotIdSubagentsByIdSkillsErrors, PostBotsByBotIdSubagentsByIdSkillsResponse, PostBotsByBotIdSubagentsByIdSkillsResponses, PostBotsByBotIdSubagentsData, PostBotsByBotIdSubagentsError, PostBotsByBotIdSubagentsErrors, PostBotsByBotIdSubagentsResponse, PostBotsByBotIdSubagentsResponses, PostBotsByBotIdToolsData, PostBotsByBotIdToolsError, PostBotsByBotIdToolsErrors, PostBotsByBotIdToolsResponse, PostBotsByBotIdToolsResponses, PostBotsByIdChannelByPlatformSendChatData, PostBotsByIdChannelByPlatformSendChatError, PostBotsByIdChannelByPlatformSendChatErrors, PostBotsByIdChannelByPlatformSendChatResponse, PostBotsByIdChannelByPlatformSendChatResponses, PostBotsByIdChannelByPlatformSendData, PostBotsByIdChannelByPlatformSendError, PostBotsByIdChannelByPlatformSendErrors, PostBotsByIdChannelByPlatformSendResponse, PostBotsByIdChannelByPlatformSendResponses, PostBotsData, PostBotsError, PostBotsErrors, PostBotsResponse, PostBotsResponses, PostEmbeddingsData, PostEmbeddingsError, PostEmbeddingsErrors, PostEmbeddingsResponse, PostEmbeddingsResponses, PostModelsData, PostModelsError, PostModelsErrors, PostModelsResponse, PostModelsResponses, PostProvidersData, PostProvidersError, PostProvidersErrors, PostProvidersResponse, PostProvidersResponses, PostSearchProvidersData, PostSearchProvidersError, PostSearchProvidersErrors, PostSearchProvidersResponse, PostSearchProvidersResponses, PostUsersData, PostUsersError, PostUsersErrors, PostUsersResponse, PostUsersResponses, ProvidersClientType, ProvidersCountResponse, ProvidersCreateRequest, ProvidersGetResponse, ProvidersUpdateRequest, PutBotsByBotIdMcpByIdData, PutBotsByBotIdMcpByIdError, PutBotsByBotIdMcpByIdErrors, PutBotsByBotIdMcpByIdResponse, PutBotsByBotIdMcpByIdResponses, PutBotsByBotIdMcpImportData, PutBotsByBotIdMcpImportError, PutBotsByBotIdMcpImportErrors, PutBotsByBotIdMcpImportResponse, PutBotsByBotIdMcpImportResponses, 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, PutSearchProvidersByIdData, PutSearchProvidersByIdError, PutSearchProvidersByIdErrors, PutSearchProvidersByIdResponse, PutSearchProvidersByIdResponses, 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, SearchprovidersCreateRequest, SearchprovidersGetResponse, SearchprovidersProviderConfigSchema, SearchprovidersProviderFieldSchema, SearchprovidersProviderMeta, SearchprovidersProviderName, SearchprovidersUpdateRequest, SettingsSettings, SettingsUpsertRequest, SubagentAddSkillsRequest, SubagentContextResponse, SubagentCreateRequest, SubagentListResponse, SubagentSkillsResponse, SubagentSubagent, SubagentUpdateContextRequest, SubagentUpdateRequest, SubagentUpdateSkillsRequest } from './types.gen'; +export type { AccountsAccount, AccountsCreateAccountRequest, AccountsListAccountsResponse, AccountsResetPasswordRequest, AccountsUpdateAccountRequest, AccountsUpdatePasswordRequest, AccountsUpdateProfileRequest, BotsBot, BotsBotCheck, BotsBotMember, BotsCreateBotRequest, BotsListBotsResponse, BotsListChecksResponse, BotsListMembersResponse, BotsTransferBotRequest, BotsUpdateBotRequest, BotsUpsertMemberRequest, ChannelAction, ChannelAttachment, ChannelAttachmentType, ChannelChannelCapabilities, ChannelChannelConfig, ChannelChannelIdentityBinding, ChannelConfigSchema, ChannelFieldSchema, ChannelFieldType, ChannelMessage, ChannelMessageFormat, ChannelMessagePart, ChannelMessagePartType, ChannelMessageTextStyle, ChannelReplyRef, ChannelSendRequest, ChannelTargetHint, ChannelTargetSpec, ChannelThreadRef, ChannelUpdateChannelStatusRequest, ChannelUpsertChannelIdentityConfigRequest, ChannelUpsertConfigRequest, ClientOptions, DeleteBotsByBotIdContainerData, DeleteBotsByBotIdContainerError, DeleteBotsByBotIdContainerErrors, DeleteBotsByBotIdContainerResponses, DeleteBotsByBotIdContainerSkillsData, DeleteBotsByBotIdContainerSkillsError, DeleteBotsByBotIdContainerSkillsErrors, DeleteBotsByBotIdContainerSkillsResponse, DeleteBotsByBotIdContainerSkillsResponses, DeleteBotsByBotIdMcpByIdData, DeleteBotsByBotIdMcpByIdError, DeleteBotsByBotIdMcpByIdErrors, DeleteBotsByBotIdMcpByIdResponses, DeleteBotsByBotIdMemoryByIdData, DeleteBotsByBotIdMemoryByIdError, DeleteBotsByBotIdMemoryByIdErrors, DeleteBotsByBotIdMemoryByIdResponse, DeleteBotsByBotIdMemoryByIdResponses, DeleteBotsByBotIdMemoryData, DeleteBotsByBotIdMemoryError, DeleteBotsByBotIdMemoryErrors, DeleteBotsByBotIdMemoryResponse, DeleteBotsByBotIdMemoryResponses, DeleteBotsByBotIdScheduleByIdData, DeleteBotsByBotIdScheduleByIdError, DeleteBotsByBotIdScheduleByIdErrors, DeleteBotsByBotIdScheduleByIdResponses, DeleteBotsByBotIdSettingsData, DeleteBotsByBotIdSettingsError, DeleteBotsByBotIdSettingsErrors, DeleteBotsByBotIdSettingsResponses, DeleteBotsByBotIdSubagentsByIdData, DeleteBotsByBotIdSubagentsByIdError, DeleteBotsByBotIdSubagentsByIdErrors, DeleteBotsByBotIdSubagentsByIdResponses, DeleteBotsByIdChannelByPlatformData, DeleteBotsByIdChannelByPlatformError, DeleteBotsByIdChannelByPlatformErrors, DeleteBotsByIdChannelByPlatformResponses, DeleteBotsByIdData, DeleteBotsByIdError, DeleteBotsByIdErrors, DeleteBotsByIdMembersByUserIdData, DeleteBotsByIdMembersByUserIdError, DeleteBotsByIdMembersByUserIdErrors, DeleteBotsByIdMembersByUserIdResponses, DeleteBotsByIdResponse, DeleteBotsByIdResponses, DeleteModelsByIdData, DeleteModelsByIdError, DeleteModelsByIdErrors, DeleteModelsByIdResponses, DeleteModelsModelByModelIdData, DeleteModelsModelByModelIdError, DeleteModelsModelByModelIdErrors, DeleteModelsModelByModelIdResponses, DeleteProvidersByIdData, DeleteProvidersByIdError, DeleteProvidersByIdErrors, DeleteProvidersByIdResponses, DeleteSearchProvidersByIdData, DeleteSearchProvidersByIdError, DeleteSearchProvidersByIdErrors, DeleteSearchProvidersByIdResponses, GetBotsByBotIdContainerData, GetBotsByBotIdContainerError, GetBotsByBotIdContainerErrors, GetBotsByBotIdContainerResponse, GetBotsByBotIdContainerResponses, GetBotsByBotIdContainerSkillsData, GetBotsByBotIdContainerSkillsError, GetBotsByBotIdContainerSkillsErrors, GetBotsByBotIdContainerSkillsResponse, GetBotsByBotIdContainerSkillsResponses, GetBotsByBotIdContainerSnapshotsData, GetBotsByBotIdContainerSnapshotsResponse, GetBotsByBotIdContainerSnapshotsResponses, GetBotsByBotIdMcpByIdData, GetBotsByBotIdMcpByIdError, GetBotsByBotIdMcpByIdErrors, GetBotsByBotIdMcpByIdResponse, GetBotsByBotIdMcpByIdResponses, GetBotsByBotIdMcpData, GetBotsByBotIdMcpError, GetBotsByBotIdMcpErrors, GetBotsByBotIdMcpExportData, GetBotsByBotIdMcpExportError, GetBotsByBotIdMcpExportErrors, GetBotsByBotIdMcpExportResponse, GetBotsByBotIdMcpExportResponses, GetBotsByBotIdMcpResponse, GetBotsByBotIdMcpResponses, GetBotsByBotIdMemoryData, GetBotsByBotIdMemoryError, GetBotsByBotIdMemoryErrors, GetBotsByBotIdMemoryResponse, GetBotsByBotIdMemoryResponses, GetBotsByBotIdMemoryUsageData, GetBotsByBotIdMemoryUsageError, GetBotsByBotIdMemoryUsageErrors, GetBotsByBotIdMemoryUsageResponse, GetBotsByBotIdMemoryUsageResponses, GetBotsByBotIdMessagesData, GetBotsByBotIdMessagesError, GetBotsByBotIdMessagesErrors, GetBotsByBotIdMessagesResponse, GetBotsByBotIdMessagesResponses, 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, GetBotsByIdChecksData, GetBotsByIdChecksError, GetBotsByIdChecksErrors, GetBotsByIdChecksResponse, GetBotsByIdChecksResponses, 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, GetSearchProvidersByIdData, GetSearchProvidersByIdError, GetSearchProvidersByIdErrors, GetSearchProvidersByIdResponse, GetSearchProvidersByIdResponses, GetSearchProvidersData, GetSearchProvidersError, GetSearchProvidersErrors, GetSearchProvidersMetaData, GetSearchProvidersMetaResponse, GetSearchProvidersMetaResponses, GetSearchProvidersResponse, GetSearchProvidersResponses, GetUsersByIdData, GetUsersByIdError, GetUsersByIdErrors, GetUsersByIdResponse, GetUsersByIdResponses, GetUsersData, GetUsersError, GetUsersErrors, GetUsersMeChannelsByPlatformData, GetUsersMeChannelsByPlatformError, GetUsersMeChannelsByPlatformErrors, GetUsersMeChannelsByPlatformResponse, GetUsersMeChannelsByPlatformResponses, GetUsersMeData, GetUsersMeError, GetUsersMeErrors, GetUsersMeIdentitiesData, GetUsersMeIdentitiesError, GetUsersMeIdentitiesErrors, GetUsersMeIdentitiesResponse, GetUsersMeIdentitiesResponses, GetUsersMeResponse, GetUsersMeResponses, GetUsersResponse, GetUsersResponses, GithubComMemohaiMemohInternalMcpConnection, HandlersBatchDeleteRequest, HandlersChannelMeta, HandlersCreateContainerRequest, HandlersCreateContainerResponse, HandlersCreateSnapshotRequest, HandlersCreateSnapshotResponse, HandlersEmbeddingsInput, HandlersEmbeddingsRequest, HandlersEmbeddingsResponse, HandlersEmbeddingsUsage, HandlersErrorResponse, HandlersGetContainerResponse, HandlersListMyIdentitiesResponse, HandlersListSnapshotsResponse, HandlersLoginRequest, HandlersLoginResponse, HandlersMcpStdioRequest, HandlersMcpStdioResponse, HandlersMemoryAddPayload, HandlersMemoryCompactPayload, HandlersMemoryDeletePayload, HandlersMemorySearchPayload, HandlersSkillItem, HandlersSkillsDeleteRequest, HandlersSkillsOpResponse, HandlersSkillsResponse, HandlersSkillsUpsertRequest, HandlersSnapshotInfo, IdentitiesChannelIdentity, McpExportResponse, McpImportRequest, McpListResponse, McpMcpServerEntry, McpUpsertRequest, MemoryCdfPoint, MemoryCompactResult, MemoryDeleteResponse, MemoryMemoryItem, MemoryMessage, MemoryRebuildResult, MemorySearchResponse, MemoryTopKBucket, MemoryUsageResponse, MessageMessage, MessageMessageAsset, ModelsAddRequest, ModelsAddResponse, ModelsClientType, ModelsCountResponse, ModelsGetResponse, ModelsModelType, ModelsUpdateRequest, PatchBotsByIdChannelByPlatformStatusData, PatchBotsByIdChannelByPlatformStatusError, PatchBotsByIdChannelByPlatformStatusErrors, PatchBotsByIdChannelByPlatformStatusResponse, PatchBotsByIdChannelByPlatformStatusResponses, PostAuthLoginData, PostAuthLoginError, PostAuthLoginErrors, PostAuthLoginResponse, PostAuthLoginResponses, PostBotsByBotIdContainerData, PostBotsByBotIdContainerError, PostBotsByBotIdContainerErrors, PostBotsByBotIdContainerResponse, PostBotsByBotIdContainerResponses, PostBotsByBotIdContainerSkillsData, PostBotsByBotIdContainerSkillsError, PostBotsByBotIdContainerSkillsErrors, PostBotsByBotIdContainerSkillsResponse, PostBotsByBotIdContainerSkillsResponses, PostBotsByBotIdContainerSnapshotsData, PostBotsByBotIdContainerSnapshotsError, PostBotsByBotIdContainerSnapshotsErrors, PostBotsByBotIdContainerSnapshotsResponse, PostBotsByBotIdContainerSnapshotsResponses, PostBotsByBotIdContainerStartData, PostBotsByBotIdContainerStartError, PostBotsByBotIdContainerStartErrors, PostBotsByBotIdContainerStartResponse, PostBotsByBotIdContainerStartResponses, PostBotsByBotIdContainerStopData, PostBotsByBotIdContainerStopError, PostBotsByBotIdContainerStopErrors, PostBotsByBotIdContainerStopResponse, PostBotsByBotIdContainerStopResponses, PostBotsByBotIdMcpData, PostBotsByBotIdMcpError, PostBotsByBotIdMcpErrors, PostBotsByBotIdMcpOpsBatchDeleteData, PostBotsByBotIdMcpOpsBatchDeleteError, PostBotsByBotIdMcpOpsBatchDeleteErrors, PostBotsByBotIdMcpOpsBatchDeleteResponses, PostBotsByBotIdMcpResponse, PostBotsByBotIdMcpResponses, PostBotsByBotIdMcpStdioByConnectionIdData, PostBotsByBotIdMcpStdioByConnectionIdError, PostBotsByBotIdMcpStdioByConnectionIdErrors, PostBotsByBotIdMcpStdioByConnectionIdResponse, PostBotsByBotIdMcpStdioByConnectionIdResponses, PostBotsByBotIdMcpStdioData, PostBotsByBotIdMcpStdioError, PostBotsByBotIdMcpStdioErrors, PostBotsByBotIdMcpStdioResponse, PostBotsByBotIdMcpStdioResponses, PostBotsByBotIdMemoryCompactData, PostBotsByBotIdMemoryCompactError, PostBotsByBotIdMemoryCompactErrors, PostBotsByBotIdMemoryCompactResponse, PostBotsByBotIdMemoryCompactResponses, PostBotsByBotIdMemoryData, PostBotsByBotIdMemoryError, PostBotsByBotIdMemoryErrors, PostBotsByBotIdMemoryRebuildData, PostBotsByBotIdMemoryRebuildError, PostBotsByBotIdMemoryRebuildErrors, PostBotsByBotIdMemoryRebuildResponse, PostBotsByBotIdMemoryRebuildResponses, PostBotsByBotIdMemoryResponse, PostBotsByBotIdMemoryResponses, PostBotsByBotIdMemorySearchData, PostBotsByBotIdMemorySearchError, PostBotsByBotIdMemorySearchErrors, PostBotsByBotIdMemorySearchResponse, PostBotsByBotIdMemorySearchResponses, PostBotsByBotIdScheduleData, PostBotsByBotIdScheduleError, PostBotsByBotIdScheduleErrors, PostBotsByBotIdScheduleResponse, PostBotsByBotIdScheduleResponses, PostBotsByBotIdSettingsData, PostBotsByBotIdSettingsError, PostBotsByBotIdSettingsErrors, PostBotsByBotIdSettingsResponse, PostBotsByBotIdSettingsResponses, PostBotsByBotIdSubagentsByIdSkillsData, PostBotsByBotIdSubagentsByIdSkillsError, PostBotsByBotIdSubagentsByIdSkillsErrors, PostBotsByBotIdSubagentsByIdSkillsResponse, PostBotsByBotIdSubagentsByIdSkillsResponses, PostBotsByBotIdSubagentsData, PostBotsByBotIdSubagentsError, PostBotsByBotIdSubagentsErrors, PostBotsByBotIdSubagentsResponse, PostBotsByBotIdSubagentsResponses, PostBotsByBotIdToolsData, PostBotsByBotIdToolsError, PostBotsByBotIdToolsErrors, PostBotsByBotIdToolsResponse, PostBotsByBotIdToolsResponses, PostBotsByIdChannelByPlatformSendChatData, PostBotsByIdChannelByPlatformSendChatError, PostBotsByIdChannelByPlatformSendChatErrors, PostBotsByIdChannelByPlatformSendChatResponse, PostBotsByIdChannelByPlatformSendChatResponses, PostBotsByIdChannelByPlatformSendData, PostBotsByIdChannelByPlatformSendError, PostBotsByIdChannelByPlatformSendErrors, PostBotsByIdChannelByPlatformSendResponse, PostBotsByIdChannelByPlatformSendResponses, PostBotsData, PostBotsError, PostBotsErrors, PostBotsResponse, PostBotsResponses, PostEmbeddingsData, PostEmbeddingsError, PostEmbeddingsErrors, PostEmbeddingsResponse, PostEmbeddingsResponses, PostModelsData, PostModelsError, PostModelsErrors, PostModelsResponse, PostModelsResponses, PostProvidersData, PostProvidersError, PostProvidersErrors, PostProvidersResponse, PostProvidersResponses, PostSearchProvidersData, PostSearchProvidersError, PostSearchProvidersErrors, PostSearchProvidersResponse, PostSearchProvidersResponses, PostUsersData, PostUsersError, PostUsersErrors, PostUsersResponse, PostUsersResponses, ProvidersCountResponse, ProvidersCreateRequest, ProvidersGetResponse, ProvidersUpdateRequest, PutBotsByBotIdMcpByIdData, PutBotsByBotIdMcpByIdError, PutBotsByBotIdMcpByIdErrors, PutBotsByBotIdMcpByIdResponse, PutBotsByBotIdMcpByIdResponses, PutBotsByBotIdMcpImportData, PutBotsByBotIdMcpImportError, PutBotsByBotIdMcpImportErrors, PutBotsByBotIdMcpImportResponse, PutBotsByBotIdMcpImportResponses, 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, PutSearchProvidersByIdData, PutSearchProvidersByIdError, PutSearchProvidersByIdErrors, PutSearchProvidersByIdResponse, PutSearchProvidersByIdResponses, 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, SearchprovidersCreateRequest, SearchprovidersGetResponse, SearchprovidersProviderConfigSchema, SearchprovidersProviderFieldSchema, SearchprovidersProviderMeta, SearchprovidersProviderName, SearchprovidersUpdateRequest, SettingsSettings, SettingsUpsertRequest, SubagentAddSkillsRequest, SubagentContextResponse, SubagentCreateRequest, SubagentListResponse, SubagentSkillsResponse, SubagentSubagent, SubagentUpdateContextRequest, SubagentUpdateRequest, SubagentUpdateSkillsRequest } from './types.gen'; diff --git a/packages/sdk/src/sdk.gen.ts b/packages/sdk/src/sdk.gen.ts index 0eedf838..a9e4a80a 100644 --- a/packages/sdk/src/sdk.gen.ts +++ b/packages/sdk/src/sdk.gen.ts @@ -813,7 +813,7 @@ export const putModelsById = (options: Opt /** * List all LLM providers * - * Get a list of all configured LLM providers, optionally filtered by client type + * Get a list of all configured LLM providers */ export const getProviders = (options?: Options) => (options?.client ?? client).get({ url: '/providers', ...options }); @@ -834,7 +834,7 @@ export const postProviders = (options: Opt /** * Count providers * - * Get the total count of providers, optionally filtered by client type + * Get the total count of providers */ export const getProvidersCount = (options?: Options) => (options?.client ?? client).get({ url: '/providers/count', ...options }); diff --git a/packages/sdk/src/types.gen.ts b/packages/sdk/src/types.gen.ts index 6af0445a..3bf2d24b 100644 --- a/packages/sdk/src/types.gen.ts +++ b/packages/sdk/src/types.gen.ts @@ -691,6 +691,7 @@ export type MessageMessageAsset = { }; export type ModelsAddRequest = { + client_type?: ModelsClientType; dimensions?: number; input_modalities?: Array; llm_provider_id?: string; @@ -704,11 +705,14 @@ export type ModelsAddResponse = { model_id?: string; }; +export type ModelsClientType = 'openai-responses' | 'openai-completions' | 'anthropic-messages' | 'google-generative-ai'; + export type ModelsCountResponse = { count?: number; }; export type ModelsGetResponse = { + client_type?: ModelsClientType; dimensions?: number; input_modalities?: Array; llm_provider_id?: string; @@ -720,6 +724,7 @@ export type ModelsGetResponse = { export type ModelsModelType = 'chat' | 'embedding'; export type ModelsUpdateRequest = { + client_type?: ModelsClientType; dimensions?: number; input_modalities?: Array; llm_provider_id?: string; @@ -728,8 +733,6 @@ export type ModelsUpdateRequest = { type?: ModelsModelType; }; -export type ProvidersClientType = 'openai' | 'openai-compat' | 'anthropic' | 'google' | 'azure' | 'bedrock' | 'mistral' | 'xai' | 'ollama' | 'dashscope'; - export type ProvidersCountResponse = { count?: number; }; @@ -737,7 +740,6 @@ export type ProvidersCountResponse = { export type ProvidersCreateRequest = { api_key?: string; base_url: string; - client_type: ProvidersClientType; metadata?: { [key: string]: unknown; }; @@ -750,7 +752,6 @@ export type ProvidersGetResponse = { */ api_key?: string; base_url?: string; - client_type?: string; created_at?: string; id?: string; metadata?: { @@ -763,7 +764,6 @@ export type ProvidersGetResponse = { export type ProvidersUpdateRequest = { api_key?: string; base_url?: string; - client_type?: ProvidersClientType; metadata?: { [key: string]: unknown; }; @@ -3671,7 +3671,7 @@ export type GetModelsData = { */ type?: string; /** - * Client type (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope) + * Client type (openai-responses, openai-completions, anthropic-messages, google-generative-ai) */ client_type?: string; }; @@ -3999,20 +3999,11 @@ export type PutModelsByIdResponse = PutModelsByIdResponses[keyof PutModelsByIdRe export type GetProvidersData = { body?: never; path?: never; - query?: { - /** - * Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope) - */ - client_type?: string; - }; + query?: never; url: '/providers'; }; export type GetProvidersErrors = { - /** - * Bad Request - */ - 400: HandlersErrorResponse; /** * Internal Server Error */ @@ -4065,20 +4056,11 @@ export type PostProvidersResponse = PostProvidersResponses[keyof PostProvidersRe export type GetProvidersCountData = { body?: never; path?: never; - query?: { - /** - * Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope) - */ - client_type?: string; - }; + query?: never; url: '/providers/count'; }; export type GetProvidersCountErrors = { - /** - * Bad Request - */ - 400: HandlersErrorResponse; /** * Internal Server Error */ diff --git a/packages/web/src/components/add-provider/index.vue b/packages/web/src/components/add-provider/index.vue index 2d20cada..af3e1dec 100644 --- a/packages/web/src/components/add-provider/index.vue +++ b/packages/web/src/components/add-provider/index.vue @@ -73,34 +73,6 @@ - - - - - - - - @@ -139,12 +111,6 @@ import { FormControl, FormItem, DialogDescription, - Select, - SelectTrigger, - SelectValue, - SelectContent, - SelectGroup, - SelectItem, Separator, Label, Spinner, @@ -154,12 +120,6 @@ import z from 'zod' import { useForm } from 'vee-validate' 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', - 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope', -] const open = defineModel('open') @@ -175,7 +135,6 @@ const { mutate: providerFetch, isLoading } = useMutation({ const providerSchema = toTypedSchema(z.object({ api_key: z.string().min(1), base_url: z.string().min(1), - client_type: z.string().min(1), name: z.string().min(1), metadata: z.object({ additionalProp1: z.object({}), diff --git a/packages/web/src/components/create-model/index.vue b/packages/web/src/components/create-model/index.vue index 841d7ae5..1f0d7147 100644 --- a/packages/web/src/components/create-model/index.vue +++ b/packages/web/src/components/create-model/index.vue @@ -46,6 +46,55 @@ + +
+ + + + + + + + + +
+ (['text']) const formSchema = toTypedSchema(z.object({ type: z.string().min(1), + client_type: z.string().optional(), model_id: z.string().min(1), name: z.string().optional(), dimensions: z.coerce.number().min(1).optional(), @@ -192,20 +246,36 @@ const formSchema = toTypedSchema(z.object({ const form = useForm({ validationSchema: formSchema, + initialValues: { + type: 'chat', + }, }) -const selectedType = computed(() => form.values.type || editInfo?.value?.type) +const selectedType = computed(() => form.values.type || 'chat') + +const clientTypeOpen = ref(false) + +const selectedClientTypeLabel = computed(() => { + const ct = form.values.client_type + if (!ct) return '' + return CLIENT_TYPE_META[ct]?.label ?? ct +}) + +function selectClientType(value: string) { + form.setFieldValue('client_type', value) + clientTypeOpen.value = false +} const open = inject>('openModel', ref(false)) const title = inject>('openModelTitle', ref('title')) const editInfo = inject>('openModelState', ref(null)) -// 保存按钮:编辑模式直接可提交(表单已预填充,handleSubmit 内部会校验) -// 新建模式需要必填字段有值 const canSubmit = computed(() => { if (title.value === 'edit') return true - const { type, model_id } = form.values - return !!type && !!model_id + const { type, model_id, client_type } = form.values + if (!type || !model_id) return false + if (type === 'chat' && !client_type) return false + return true }) function toggleModality(mod: string, checked: boolean) { @@ -216,14 +286,6 @@ function toggleModality(mod: string, checked: boolean) { } } -const emptyValues = { - type: '' as string, - model_id: '' as string, - name: '' as string, - dimensions: undefined as number | undefined, -} - -// Display Name 自动跟随 Model ID,除非用户主动修改过 const userEditedName = ref(false) watch( @@ -269,14 +331,16 @@ async function addModel(e: Event) { const isEdit = title.value === 'edit' && !!editInfo?.value const fallback = editInfo?.value - // 从 form.values 读取,编辑模式用 editInfo 兜底 - // (Dialog 异步渲染可能导致 vee-validate 内部状态未同步) - const type = form.values.type || (isEdit ? fallback!.type : '') + const type = form.values.type || (isEdit ? fallback!.type : 'chat') + const client_type = type === 'chat' + ? (form.values.client_type || (isEdit ? fallback!.client_type : '')) + : undefined const model_id = form.values.model_id || (isEdit ? fallback!.model_id : '') const name = form.values.name ?? (isEdit ? fallback!.name : '') const dimensions = form.values.dimensions ?? (isEdit ? fallback!.dimensions : undefined) if (!type || !model_id) return + if (type === 'chat' && !client_type) return try { const payload: Record = { @@ -285,6 +349,10 @@ async function addModel(e: Event) { llm_provider_id: id, } + if (type === 'chat' && client_type) { + payload.client_type = client_type + } + if (name) { payload.name = name } @@ -315,20 +383,26 @@ watch(open, async () => { return } - // 等待 Dialog 内容和 FormField 组件挂载完成 await nextTick() if (editInfo?.value) { - const { type, model_id, name, dimensions, input_modalities } = editInfo.value - form.resetForm({ values: { type, model_id, name, dimensions } }) + const { client_type, type, model_id, name, dimensions, input_modalities } = editInfo.value + form.resetForm({ values: { type: type || 'chat', client_type: client_type || '', model_id, name, dimensions } }) selectedModalities.value = input_modalities ?? ['text'] userEditedName.value = !!(name && name !== model_id) } else { - form.resetForm({ values: { ...emptyValues } }) + form.resetForm({ values: { type: 'chat', client_type: '', model_id: '', name: '', dimensions: undefined } }) selectedModalities.value = ['text'] userEditedName.value = false } }, { immediate: true, }) + +// Clear client_type when switching to embedding +watch(selectedType, (newType) => { + if (newType === 'embedding') { + form.setFieldValue('client_type', '') + } +}) diff --git a/packages/web/src/constants/client-types.ts b/packages/web/src/constants/client-types.ts new file mode 100644 index 00000000..ba32965f --- /dev/null +++ b/packages/web/src/constants/client-types.ts @@ -0,0 +1,32 @@ +import type { ModelsClientType } from '@memoh/sdk' + +export interface ClientTypeMeta { + value: ModelsClientType + label: string + hint: string +} + +export const CLIENT_TYPE_META: Record = { + 'openai-responses': { + value: 'openai-responses', + label: 'OpenAI Responses', + hint: '/v1/responses', + }, + 'openai-completions': { + value: 'openai-completions', + label: 'OpenAI Completions', + hint: '/v1/chat/completions', + }, + 'anthropic-messages': { + value: 'anthropic-messages', + label: 'Anthropic Messages', + hint: '/v1/messages', + }, + 'google-generative-ai': { + value: 'google-generative-ai', + label: 'Google Generative AI', + hint: 'Gemini API', + }, +} + +export const CLIENT_TYPE_LIST: ClientTypeMeta[] = Object.values(CLIENT_TYPE_META) diff --git a/packages/web/src/i18n/locales/en.json b/packages/web/src/i18n/locales/en.json index 86559792..13826ac0 100644 --- a/packages/web/src/i18n/locales/en.json +++ b/packages/web/src/i18n/locales/en.json @@ -143,6 +143,8 @@ "deleteModelConfirm": "Are you sure you want to delete this model?", "emptyTitle": "No Models", "emptyDescription": "Click the button above to add a model for this provider", + "clientType": "Client Type", + "clientTypePlaceholder": "Select client type", "model": "Model ID", "modelPlaceholder": "e.g. gpt-4o", "displayName": "Display Name", diff --git a/packages/web/src/i18n/locales/zh.json b/packages/web/src/i18n/locales/zh.json index 1a30bbaf..418a4660 100644 --- a/packages/web/src/i18n/locales/zh.json +++ b/packages/web/src/i18n/locales/zh.json @@ -139,6 +139,8 @@ "deleteModelConfirm": "确定要删除这个模型吗?", "emptyTitle": "暂无模型", "emptyDescription": "点击上方按钮为当前服务商添加模型", + "clientType": "客户端类型", + "clientTypePlaceholder": "选择客户端类型", "model": "模型 ID", "modelPlaceholder": "例如 gpt-4o", "displayName": "显示名称", diff --git a/packages/web/src/pages/models/components/model-item.vue b/packages/web/src/pages/models/components/model-item.vue index ea0f4ff6..e0ee0bed 100644 --- a/packages/web/src/pages/models/components/model-item.vue +++ b/packages/web/src/pages/models/components/model-item.vue @@ -6,6 +6,12 @@ {{ model.type }} + + {{ model.client_type }} + diff --git a/packages/web/src/pages/models/components/provider-form.vue b/packages/web/src/pages/models/components/provider-form.vue index 4b6c8538..8153a1fb 100644 --- a/packages/web/src/pages/models/components/provider-form.vue +++ b/packages/web/src/pages/models/components/provider-form.vue @@ -116,7 +116,6 @@ const emit = defineEmits<{ const providerSchema = toTypedSchema(z.object({ name: z.string().min(1), base_url: z.string().min(1), - client_type: z.string().min(1), api_key: z.string().optional(), metadata: z.object({ additionalProp1: z.object({}), @@ -132,8 +131,6 @@ watch(() => props.provider, (newVal) => { form.setValues({ name: newVal.name, base_url: newVal.base_url, - client_type: newVal.client_type, - // Keep key input empty by default so masked placeholders are never submitted back. api_key: '', }) } @@ -144,12 +141,10 @@ const hasChanges = computed(() => { const baseChanged = JSON.stringify({ name: form.values.name, base_url: form.values.base_url, - client_type: form.values.client_type, metadata: form.values.metadata, }) !== JSON.stringify({ name: raw?.name, base_url: raw?.base_url, - client_type: raw?.client_type, metadata: { additionalProp1: {} }, }) @@ -161,7 +156,6 @@ const editProvider = form.handleSubmit(async (value) => { const payload: Record = { name: value.name, base_url: value.base_url, - client_type: value.client_type, metadata: value.metadata, } if (value.api_key && value.api_key.trim() !== '') { diff --git a/packages/web/src/pages/models/index.vue b/packages/web/src/pages/models/index.vue index b124b503..b6f868c1 100644 --- a/packages/web/src/pages/models/index.vue +++ b/packages/web/src/pages/models/index.vue @@ -14,12 +14,6 @@ import { InputGroup, InputGroupAddon, InputGroupInput, SidebarFooter, Toggle, - Select, - SelectTrigger, - SelectValue, - SelectContent, - SelectGroup, - SelectItem, Empty, EmptyContent, EmptyDescription, @@ -28,21 +22,14 @@ import { EmptyTitle, } from '@memoh/ui' import { getProviders } from '@memoh/sdk' -import type { ProvidersGetResponse, ProvidersClientType } from '@memoh/sdk' +import type { ProvidersGetResponse } from '@memoh/sdk' import AddProvider from '@/components/add-provider/index.vue' import { useQuery } from '@pinia/colada' -const CLIENT_TYPES: ProvidersClientType[] = [ - 'openai', 'openai-compat', 'anthropic', 'google', - 'azure', 'bedrock', 'mistral', 'xai', 'ollama', 'dashscope', -] - -const filterProvider = ref('') const { data: providerData } = useQuery({ - key: () => ['providers', filterProvider.value], + key: () => ['providers'], query: async () => { const { data } = await getProviders({ - query: filterProvider.value ? { client_type: filterProvider.value } : undefined, throwOnError: true, }) return data @@ -50,10 +37,6 @@ const { data: providerData } = useQuery({ }) const queryCache = useQueryCache() -watch(filterProvider, () => { - queryCache.invalidateQueries({ key: ['providers'] }) -}, { immediate: true }) - const curProvider = ref() provide('curProvider', curProvider) @@ -142,22 +125,6 @@ const openStatus = reactive({ - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a6672a4f..8fcf04c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,30 +45,18 @@ importers: agent: dependencies: - '@ai-sdk/amazon-bedrock': - specifier: ^4.0.56 - version: 4.0.56(zod@4.3.5) '@ai-sdk/anthropic': specifier: ^3.0.9 version: 3.0.9(zod@4.3.5) - '@ai-sdk/azure': - specifier: ^3.0.28 - version: 3.0.28(zod@4.3.5) '@ai-sdk/google': specifier: ^3.0.6 version: 3.0.6(zod@4.3.5) '@ai-sdk/mcp': specifier: ^1.0.6 version: 1.0.6(zod@4.3.5) - '@ai-sdk/mistral': - specifier: ^3.0.19 - version: 3.0.19(zod@4.3.5) '@ai-sdk/openai': specifier: ^3.0.7 version: 3.0.7(zod@4.3.5) - '@ai-sdk/xai': - specifier: ^3.0.54 - version: 3.0.54(zod@4.3.5) '@elysiajs/bearer': specifier: ^1.4.2 version: 1.4.2(elysia@1.4.22(@sinclair/typebox@0.34.47)(@types/bun@1.3.8)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)) @@ -382,30 +370,12 @@ packages: '@acemir/cssom@0.9.31': resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} - '@ai-sdk/amazon-bedrock@4.0.56': - resolution: {integrity: sha512-LOJud09s2zUFYsMGOHv55m3ERxDrZ6+1PpcsihWUPloA4DcXJZIVRABck9OCU5NvUWR75jxsymg/+p79ox6IOw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/anthropic@3.0.42': - resolution: {integrity: sha512-snoLXB9DmvAmmngbPN/Io8IGzZ9zWpC208EgIIztYf1e1JhwuMkgKCYkL30vGhSen4PrBafu2+sO4G/17wu45A==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/anthropic@3.0.9': resolution: {integrity: sha512-QBD4qDnwIHd+N5PpjxXOaWJig1aRB43J0PM5ZUe6Yyl9Qq2bUmraQjvNznkuFKy+hMFDgj0AvgGogTiO5TC+qA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/azure@3.0.28': - resolution: {integrity: sha512-FDzx/MF7M9boJ7pB5zMUwbGU2HadYM0ZsI7b/sPiHKecwirk7Endl9RtwGrfjauPDrRnP0W+djMc2NhKwp0B8w==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/gateway@3.0.10': resolution: {integrity: sha512-sRlPMKd38+fdp2y11USW44c0o8tsIsT6T/pgyY04VXC3URjIRnkxugxd9AkU2ogfpPDMz50cBAGPnMxj+6663Q==} engines: {node: '>=18'} @@ -424,36 +394,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/mistral@3.0.19': - resolution: {integrity: sha512-yd0OJ3fm2YKdwxh1pd9m720sENVVcylAD+Bki8C80QqVpUxGNL1/C4N4JJGb56eCCWr6VU/3gHFe9PKui9n/Hg==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/openai-compatible@2.0.29': - resolution: {integrity: sha512-yoZ+jxBzVA7cQIrcOn2ZXAVeqsNdhqFGWW3VwTJwNnmeOLCACoz6+pu58LY/zjxEJGVrl5X+JazdY5LhDMey8A==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - - '@ai-sdk/openai@3.0.27': - resolution: {integrity: sha512-pLMxWOypwroXiK9dxNpn60/HGhWWWDEOJ3lo9vZLoxvpJNtKnLKojwVIvlW3yEjlD7ll1+jUO2uzsABNTaP5Yg==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/openai@3.0.7': resolution: {integrity: sha512-CBoYn1U59Lop8yBL9KuVjHCKc/B06q9Qo0SasRwHoyMEq+X4I8LQZu3a8Ck1jwwcZTTxfyiExB70LtIRSynBDA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.14': - resolution: {integrity: sha512-7bzKd9lgiDeXM7O4U4nQ8iTxguAOkg8LZGD9AfDVZYjO5cKYRwBPwVjboFcVrxncRHu0tYxZtXZtiLKpG4pEng==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.4': resolution: {integrity: sha512-VxhX0B/dWGbpNHxrKCWUAJKXIXV015J4e7qYjdIU9lLWeptk0KMLGcqkB4wFxff5Njqur8dt8wRi1MN9lZtDqg==} engines: {node: '>=18'} @@ -470,16 +416,6 @@ packages: resolution: {integrity: sha512-HrEmNt/BH/hkQ7zpi2o6N3k1ZR1QTb7z85WYhYygiTxOQuaml4CMtHCWRbric5WPU+RNsYI7r1EpyVQMKO1pYw==} engines: {node: '>=18'} - '@ai-sdk/provider@3.0.8': - resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} - engines: {node: '>=18'} - - '@ai-sdk/xai@3.0.54': - resolution: {integrity: sha512-zWKj5v3cmJAc5aZ4iY1jB2rmqMhXVLdMHAk76srSByTmPnssGaW9XNvIgyCAD2WD1g14P3YjRg1FTK+K2Z2Bjw==} - engines: {node: '>=18'} - peerDependencies: - zod: ^3.25.76 || ^4.1.8 - '@algolia/abtesting@1.12.2': resolution: {integrity: sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==} engines: {node: '>= 14.0.0'} @@ -568,17 +504,6 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} - '@aws-crypto/crc32@5.2.0': - resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} - engines: {node: '>=16.0.0'} - - '@aws-crypto/util@5.2.0': - resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - - '@aws-sdk/types@3.973.1': - resolution: {integrity: sha512-DwHBiMNOB468JiX6+i34c+THsKHErYUdNQ3HexeXZvVn4zouLjgaS4FejiGSi2HyBuzuyHg7SuOPmjSvoU9NRg==} - engines: {node: '>=20.0.0'} - '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -1980,42 +1905,6 @@ packages: '@sinclair/typebox@0.34.47': resolution: {integrity: sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==} - '@smithy/eventstream-codec@4.2.8': - resolution: {integrity: sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw==} - engines: {node: '>=18.0.0'} - - '@smithy/is-array-buffer@2.2.0': - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} - - '@smithy/is-array-buffer@4.2.0': - resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.12.0': - resolution: {integrity: sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-buffer-from@2.2.0': - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} - - '@smithy/util-buffer-from@4.2.0': - resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} - engines: {node: '>=18.0.0'} - - '@smithy/util-hex-encoding@4.2.0': - resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-utf8@2.3.0': - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} - - '@smithy/util-utf8@4.2.0': - resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} - engines: {node: '>=18.0.0'} - '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2681,9 +2570,6 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - aws4fetch@1.0.20: - resolution: {integrity: sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g==} - axios@1.13.4: resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} @@ -5241,35 +5127,12 @@ snapshots: '@acemir/cssom@0.9.31': {} - '@ai-sdk/amazon-bedrock@4.0.56(zod@4.3.5)': - dependencies: - '@ai-sdk/anthropic': 3.0.42(zod@4.3.5) - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - '@smithy/eventstream-codec': 4.2.8 - '@smithy/util-utf8': 4.2.0 - aws4fetch: 1.0.20 - zod: 4.3.5 - - '@ai-sdk/anthropic@3.0.42(zod@4.3.5)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - '@ai-sdk/anthropic@3.0.9(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.2 '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) zod: 4.3.5 - '@ai-sdk/azure@3.0.28(zod@4.3.5)': - dependencies: - '@ai-sdk/openai': 3.0.27(zod@4.3.5) - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - '@ai-sdk/gateway@3.0.10(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.2 @@ -5290,37 +5153,12 @@ snapshots: pkce-challenge: 5.0.1 zod: 4.3.5 - '@ai-sdk/mistral@3.0.19(zod@4.3.5)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - - '@ai-sdk/openai-compatible@2.0.29(zod@4.3.5)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - - '@ai-sdk/openai@3.0.27(zod@4.3.5)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - '@ai-sdk/openai@3.0.7(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.2 '@ai-sdk/provider-utils': 4.0.4(zod@4.3.5) zod: 4.3.5 - '@ai-sdk/provider-utils@4.0.14(zod@4.3.5)': - dependencies: - '@ai-sdk/provider': 3.0.8 - '@standard-schema/spec': 1.1.0 - eventsource-parser: 3.0.6 - zod: 4.3.5 - '@ai-sdk/provider-utils@4.0.4(zod@4.3.5)': dependencies: '@ai-sdk/provider': 3.0.2 @@ -5339,17 +5177,6 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/provider@3.0.8': - dependencies: - json-schema: 0.4.0 - - '@ai-sdk/xai@3.0.54(zod@4.3.5)': - dependencies: - '@ai-sdk/openai-compatible': 2.0.29(zod@4.3.5) - '@ai-sdk/provider': 3.0.8 - '@ai-sdk/provider-utils': 4.0.14(zod@4.3.5) - zod: 4.3.5 - '@algolia/abtesting@1.12.2': dependencies: '@algolia/client-common': 5.46.2 @@ -5485,23 +5312,6 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': {} - '@aws-crypto/crc32@5.2.0': - dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.1 - tslib: 2.8.1 - - '@aws-crypto/util@5.2.0': - dependencies: - '@aws-sdk/types': 3.973.1 - '@smithy/util-utf8': 2.3.0 - tslib: 2.8.1 - - '@aws-sdk/types@3.973.1': - dependencies: - '@smithy/types': 4.12.0 - tslib: 2.8.1 - '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -6749,49 +6559,6 @@ snapshots: '@sinclair/typebox@0.34.47': {} - '@smithy/eventstream-codec@4.2.8': - dependencies: - '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.12.0 - '@smithy/util-hex-encoding': 4.2.0 - tslib: 2.8.1 - - '@smithy/is-array-buffer@2.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/is-array-buffer@4.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/types@4.12.0': - dependencies: - tslib: 2.8.1 - - '@smithy/util-buffer-from@2.2.0': - dependencies: - '@smithy/is-array-buffer': 2.2.0 - tslib: 2.8.1 - - '@smithy/util-buffer-from@4.2.0': - dependencies: - '@smithy/is-array-buffer': 4.2.0 - tslib: 2.8.1 - - '@smithy/util-hex-encoding@4.2.0': - dependencies: - tslib: 2.8.1 - - '@smithy/util-utf8@2.3.0': - dependencies: - '@smithy/util-buffer-from': 2.2.0 - tslib: 2.8.1 - - '@smithy/util-utf8@4.2.0': - dependencies: - '@smithy/util-buffer-from': 4.2.0 - tslib: 2.8.1 - '@standard-schema/spec@1.1.0': {} '@swc/helpers@0.5.18': @@ -7548,8 +7315,6 @@ snapshots: asynckit@0.4.0: optional: true - aws4fetch@1.0.20: {} - axios@1.13.4: dependencies: follow-redirects: 1.15.11 diff --git a/spec/docs.go b/spec/docs.go index 77df3d75..aa3d2f69 100644 --- a/spec/docs.go +++ b/spec/docs.go @@ -3322,7 +3322,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Client type (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", + "description": "Client type (openai-responses, openai-completions, anthropic-messages, google-generative-ai)", "name": "client_type", "in": "query" } @@ -3697,7 +3697,7 @@ const docTemplate = `{ }, "/providers": { "get": { - "description": "Get a list of all configured LLM providers, optionally filtered by client type", + "description": "Get a list of all configured LLM providers", "consumes": [ "application/json" ], @@ -3708,14 +3708,6 @@ const docTemplate = `{ "providers" ], "summary": "List all LLM providers", - "parameters": [ - { - "type": "string", - "description": "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", - "name": "client_type", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -3726,12 +3718,6 @@ const docTemplate = `{ } } }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/handlers.ErrorResponse" - } - }, "500": { "description": "Internal Server Error", "schema": { @@ -3787,7 +3773,7 @@ const docTemplate = `{ }, "/providers/count": { "get": { - "description": "Get the total count of providers, optionally filtered by client type", + "description": "Get the total count of providers", "consumes": [ "application/json" ], @@ -3798,14 +3784,6 @@ const docTemplate = `{ "providers" ], "summary": "Count providers", - "parameters": [ - { - "type": "string", - "description": "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", - "name": "client_type", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -3813,12 +3791,6 @@ const docTemplate = `{ "$ref": "#/definitions/providers.CountResponse" } }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/handlers.ErrorResponse" - } - }, "500": { "description": "Internal Server Error", "schema": { @@ -6501,6 +6473,9 @@ const docTemplate = `{ "models.AddRequest": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6535,6 +6510,21 @@ const docTemplate = `{ } } }, + "models.ClientType": { + "type": "string", + "enum": [ + "openai-responses", + "openai-completions", + "anthropic-messages", + "google-generative-ai" + ], + "x-enum-varnames": [ + "ClientTypeOpenAIResponses", + "ClientTypeOpenAICompletions", + "ClientTypeAnthropicMessages", + "ClientTypeGoogleGenerativeAI" + ] + }, "models.CountResponse": { "type": "object", "properties": { @@ -6546,6 +6536,9 @@ const docTemplate = `{ "models.GetResponse": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6583,6 +6576,9 @@ const docTemplate = `{ "models.UpdateRequest": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6606,33 +6602,6 @@ const docTemplate = `{ } } }, - "providers.ClientType": { - "type": "string", - "enum": [ - "openai", - "openai-compat", - "anthropic", - "google", - "azure", - "bedrock", - "mistral", - "xai", - "ollama", - "dashscope" - ], - "x-enum-varnames": [ - "ClientTypeOpenAI", - "ClientTypeOpenAICompat", - "ClientTypeAnthropic", - "ClientTypeGoogle", - "ClientTypeAzure", - "ClientTypeBedrock", - "ClientTypeMistral", - "ClientTypeXAI", - "ClientTypeOllama", - "ClientTypeDashscope" - ] - }, "providers.CountResponse": { "type": "object", "properties": { @@ -6645,7 +6614,6 @@ const docTemplate = `{ "type": "object", "required": [ "base_url", - "client_type", "name" ], "properties": { @@ -6655,9 +6623,6 @@ const docTemplate = `{ "base_url": { "type": "string" }, - "client_type": { - "$ref": "#/definitions/providers.ClientType" - }, "metadata": { "type": "object", "additionalProperties": {} @@ -6677,9 +6642,6 @@ const docTemplate = `{ "base_url": { "type": "string" }, - "client_type": { - "type": "string" - }, "created_at": { "type": "string" }, @@ -6707,9 +6669,6 @@ const docTemplate = `{ "base_url": { "type": "string" }, - "client_type": { - "$ref": "#/definitions/providers.ClientType" - }, "metadata": { "type": "object", "additionalProperties": {} diff --git a/spec/swagger.json b/spec/swagger.json index f9590be1..584e4d9e 100644 --- a/spec/swagger.json +++ b/spec/swagger.json @@ -3313,7 +3313,7 @@ }, { "type": "string", - "description": "Client type (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", + "description": "Client type (openai-responses, openai-completions, anthropic-messages, google-generative-ai)", "name": "client_type", "in": "query" } @@ -3688,7 +3688,7 @@ }, "/providers": { "get": { - "description": "Get a list of all configured LLM providers, optionally filtered by client type", + "description": "Get a list of all configured LLM providers", "consumes": [ "application/json" ], @@ -3699,14 +3699,6 @@ "providers" ], "summary": "List all LLM providers", - "parameters": [ - { - "type": "string", - "description": "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", - "name": "client_type", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -3717,12 +3709,6 @@ } } }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/handlers.ErrorResponse" - } - }, "500": { "description": "Internal Server Error", "schema": { @@ -3778,7 +3764,7 @@ }, "/providers/count": { "get": { - "description": "Get the total count of providers, optionally filtered by client type", + "description": "Get the total count of providers", "consumes": [ "application/json" ], @@ -3789,14 +3775,6 @@ "providers" ], "summary": "Count providers", - "parameters": [ - { - "type": "string", - "description": "Client type filter (openai, openai-compat, anthropic, google, azure, bedrock, mistral, xai, ollama, dashscope)", - "name": "client_type", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -3804,12 +3782,6 @@ "$ref": "#/definitions/providers.CountResponse" } }, - "400": { - "description": "Bad Request", - "schema": { - "$ref": "#/definitions/handlers.ErrorResponse" - } - }, "500": { "description": "Internal Server Error", "schema": { @@ -6492,6 +6464,9 @@ "models.AddRequest": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6526,6 +6501,21 @@ } } }, + "models.ClientType": { + "type": "string", + "enum": [ + "openai-responses", + "openai-completions", + "anthropic-messages", + "google-generative-ai" + ], + "x-enum-varnames": [ + "ClientTypeOpenAIResponses", + "ClientTypeOpenAICompletions", + "ClientTypeAnthropicMessages", + "ClientTypeGoogleGenerativeAI" + ] + }, "models.CountResponse": { "type": "object", "properties": { @@ -6537,6 +6527,9 @@ "models.GetResponse": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6574,6 +6567,9 @@ "models.UpdateRequest": { "type": "object", "properties": { + "client_type": { + "$ref": "#/definitions/models.ClientType" + }, "dimensions": { "type": "integer" }, @@ -6597,33 +6593,6 @@ } } }, - "providers.ClientType": { - "type": "string", - "enum": [ - "openai", - "openai-compat", - "anthropic", - "google", - "azure", - "bedrock", - "mistral", - "xai", - "ollama", - "dashscope" - ], - "x-enum-varnames": [ - "ClientTypeOpenAI", - "ClientTypeOpenAICompat", - "ClientTypeAnthropic", - "ClientTypeGoogle", - "ClientTypeAzure", - "ClientTypeBedrock", - "ClientTypeMistral", - "ClientTypeXAI", - "ClientTypeOllama", - "ClientTypeDashscope" - ] - }, "providers.CountResponse": { "type": "object", "properties": { @@ -6636,7 +6605,6 @@ "type": "object", "required": [ "base_url", - "client_type", "name" ], "properties": { @@ -6646,9 +6614,6 @@ "base_url": { "type": "string" }, - "client_type": { - "$ref": "#/definitions/providers.ClientType" - }, "metadata": { "type": "object", "additionalProperties": {} @@ -6668,9 +6633,6 @@ "base_url": { "type": "string" }, - "client_type": { - "type": "string" - }, "created_at": { "type": "string" }, @@ -6698,9 +6660,6 @@ "base_url": { "type": "string" }, - "client_type": { - "$ref": "#/definitions/providers.ClientType" - }, "metadata": { "type": "object", "additionalProperties": {} diff --git a/spec/swagger.yaml b/spec/swagger.yaml index 61854363..7f657167 100644 --- a/spec/swagger.yaml +++ b/spec/swagger.yaml @@ -1133,6 +1133,8 @@ definitions: type: object models.AddRequest: properties: + client_type: + $ref: '#/definitions/models.ClientType' dimensions: type: integer input_modalities: @@ -1155,6 +1157,18 @@ definitions: model_id: type: string type: object + models.ClientType: + enum: + - openai-responses + - openai-completions + - anthropic-messages + - google-generative-ai + type: string + x-enum-varnames: + - ClientTypeOpenAIResponses + - ClientTypeOpenAICompletions + - ClientTypeAnthropicMessages + - ClientTypeGoogleGenerativeAI models.CountResponse: properties: count: @@ -1162,6 +1176,8 @@ definitions: type: object models.GetResponse: properties: + client_type: + $ref: '#/definitions/models.ClientType' dimensions: type: integer input_modalities: @@ -1187,6 +1203,8 @@ definitions: - ModelTypeEmbedding models.UpdateRequest: properties: + client_type: + $ref: '#/definitions/models.ClientType' dimensions: type: integer input_modalities: @@ -1202,30 +1220,6 @@ definitions: type: $ref: '#/definitions/models.ModelType' type: object - providers.ClientType: - enum: - - openai - - openai-compat - - anthropic - - google - - azure - - bedrock - - mistral - - xai - - ollama - - dashscope - type: string - x-enum-varnames: - - ClientTypeOpenAI - - ClientTypeOpenAICompat - - ClientTypeAnthropic - - ClientTypeGoogle - - ClientTypeAzure - - ClientTypeBedrock - - ClientTypeMistral - - ClientTypeXAI - - ClientTypeOllama - - ClientTypeDashscope providers.CountResponse: properties: count: @@ -1237,8 +1231,6 @@ definitions: type: string base_url: type: string - client_type: - $ref: '#/definitions/providers.ClientType' metadata: additionalProperties: {} type: object @@ -1246,7 +1238,6 @@ definitions: type: string required: - base_url - - client_type - name type: object providers.GetResponse: @@ -1256,8 +1247,6 @@ definitions: type: string base_url: type: string - client_type: - type: string created_at: type: string id: @@ -1276,8 +1265,6 @@ definitions: type: string base_url: type: string - client_type: - $ref: '#/definitions/providers.ClientType' metadata: additionalProperties: {} type: object @@ -3774,8 +3761,8 @@ paths: in: query name: type type: string - - description: Client type (openai, openai-compat, anthropic, google, azure, - bedrock, mistral, xai, ollama, dashscope) + - description: Client type (openai-responses, openai-completions, anthropic-messages, + google-generative-ai) in: query name: client_type type: string @@ -4028,14 +4015,7 @@ paths: get: consumes: - application/json - description: Get a list of all configured LLM providers, optionally filtered - by client type - parameters: - - description: Client type filter (openai, openai-compat, anthropic, google, - azure, bedrock, mistral, xai, ollama, dashscope) - in: query - name: client_type - type: string + description: Get a list of all configured LLM providers produces: - application/json responses: @@ -4045,10 +4025,6 @@ paths: items: $ref: '#/definitions/providers.GetResponse' type: array - "400": - description: Bad Request - schema: - $ref: '#/definitions/handlers.ErrorResponse' "500": description: Internal Server Error schema: @@ -4225,14 +4201,7 @@ paths: get: consumes: - application/json - description: Get the total count of providers, optionally filtered by client - type - parameters: - - description: Client type filter (openai, openai-compat, anthropic, google, - azure, bedrock, mistral, xai, ollama, dashscope) - in: query - name: client_type - type: string + description: Get the total count of providers produces: - application/json responses: @@ -4240,10 +4209,6 @@ paths: description: OK schema: $ref: '#/definitions/providers.CountResponse' - "400": - description: Bad Request - schema: - $ref: '#/definitions/handlers.ErrorResponse' "500": description: Internal Server Error schema: