diff --git a/src/ts/model/modellist.ts b/src/ts/model/modellist.ts index 2a01248190..3f55e67094 100644 --- a/src/ts/model/modellist.ts +++ b/src/ts/model/modellist.ts @@ -13,6 +13,7 @@ import { import { OpenAIModels } from './providers/openai' import { AnthropicModels } from './providers/anthropic' import { GoogleModels } from './providers/google' +import { IonetModels } from './providers/ionet' import { fetchNative } from "../globalApi.svelte" import { DBState } from "../stores.svelte" import { customProviderStore, pluginV2 } from "../plugins/plugins.svelte" @@ -44,6 +45,7 @@ function makeDeepInfraModels(id:string[]):LLMModel[]{ export const LLMModels: LLMModel[] = [ ...OpenAIModels, ...AnthropicModels, + ...IonetModels, // AWS Bedrock Claude models { name: "Claude 4.6 Opus v1", diff --git a/src/ts/model/providers/ionet.ts b/src/ts/model/providers/ionet.ts new file mode 100644 index 0000000000..a72c096fe9 --- /dev/null +++ b/src/ts/model/providers/ionet.ts @@ -0,0 +1,84 @@ +import { LLMFlags, LLMFormat, LLMProvider, LLMTokenizer, type LLMModel } from '../types' + +// IO Intelligence (io.net) — OpenAI-compatible Chat Completions gateway. +// Endpoint: https://api.intelligence.io.solutions/api/v1/chat/completions +// Model ids are org/name style (e.g. meta-llama/Llama-3.3-70B-Instruct), so +// internalID carries the wire id and id stays a friendly unique key. +// API keys: https://cloud.io.net + +export const IonetModels: LLMModel[] = [ + { + id: 'ionet/glm-5.3', + internalID: 'zai-org/GLM-5.3', + name: 'GLM 5.3 (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.GLM5, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet', + recommended: true + }, + { + id: 'ionet/deepseek-v4.1-flash', + internalID: 'deepseek-ai/DeepSeek-V4.1-Flash', + name: 'DeepSeek V4.1 Flash (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.DeepSeekV4, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet', + recommended: true + }, + { + id: 'ionet/kimi-k3', + internalID: 'moonshotai/Kimi-K3', + name: 'Kimi K3 (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt, LLMFlags.hasImageInput], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.Unknown, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet' + }, + { + id: 'ionet/qwen3.8-27b', + internalID: 'Qwen/Qwen3.8-27B', + name: 'Qwen3.8 27B (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt, LLMFlags.hasImageInput], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.Unknown, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet' + }, + { + id: 'ionet/deepseek-r1-0528', + internalID: 'deepseek-ai/DeepSeek-R1-0528', + name: 'DeepSeek R1 0528 (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.DeepSeek, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet' + }, + { + id: 'ionet/llama-3.3-70b', + internalID: 'meta-llama/Llama-3.3-70B-Instruct', + name: 'Llama 3.3 70B (IO Intelligence)', + provider: LLMProvider.Ionet, + format: LLMFormat.OpenAICompatible, + flags: [LLMFlags.hasStreaming, LLMFlags.hasFullSystemPrompt], + parameters: ['frequency_penalty', 'presence_penalty', 'temperature', 'top_p'], + tokenizer: LLMTokenizer.Llama3, + endpoint: 'https://api.intelligence.io.solutions/api/v1/chat/completions', + keyIdentifier: 'ionet' + } +] diff --git a/src/ts/model/types.ts b/src/ts/model/types.ts index bda9e9d376..6e1feff85a 100644 --- a/src/ts/model/types.ts +++ b/src/ts/model/types.ts @@ -48,7 +48,8 @@ export const LLMProvider = { DeepInfra: 13, Echo: 14, NanoGPT: 15, - Ollama: 16 + Ollama: 16, + Ionet: 17 } as const; export type LLMProvider = (typeof LLMProvider)[keyof typeof LLMProvider]; @@ -134,7 +135,8 @@ export const ProviderNames = new Map([ [LLMProvider.DeepInfra, 'DeepInfra'], [LLMProvider.Echo, 'For Developer'], [LLMProvider.NanoGPT, 'NanoGPT'], - [LLMProvider.Ollama, 'Ollama'] + [LLMProvider.Ollama, 'Ollama'], + [LLMProvider.Ionet, 'IO Intelligence'] ]) export const OpenAIParameters:LLMParameter[] = ['temperature', 'top_p', 'frequency_penalty', 'presence_penalty'] diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index dbb7399403..6f23c4ffd6 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -196,6 +196,8 @@ export async function encode(data:string):Promise<(number[]|Uint32Array|Int32Arr result = await tokenizeWebTokenizers(data, 'GLM4'); } else if(modelInfo.tokenizer === LLMTokenizer.GLM5){ result = await tokenizeWebTokenizers(data, 'GLM5'); + } else if(modelInfo.tokenizer === LLMTokenizer.Llama3){ + result = await tokenizeWebTokenizers(data, 'llama3'); } else if(modelInfo.tokenizer === LLMTokenizer.Cohere){ result = await tokenizeWebTokenizers(data, 'cohere'); } else {