1 line
18 KiB
JSON
1 line
18 KiB
JSON
{"repo": "438417623wq/yuan-ai", "files": {"lib/src/models.dart": {"551d3481bce98047122dc3e6cadb79917005c420": {"t": 1785745908.0193753, "n": 16935, "h": "9b2ed05f1335068b", "c": "import 'package:flutter/material.dart';\n\nenum ChatRole { user, assistant, system }\n\nclass ChatMessage {\n const ChatMessage({\n required this.role,\n required this.text,\n required this.time,\n });\n\n final ChatRole role;\n final String text;\n final String time;\n\n Map<String, dynamic> toJson() {\n return <String, dynamic>{'role': role.name, 'text': text, 'time': time};\n }\n\n static ChatMessage fromJson(Map<String, dynamic> json) {\n final roleName = (json['role'] ?? 'assistant').toString();\n final role = ChatRole.values.firstWhere(\n (value) => value.name == roleName,\n orElse: () => ChatRole.assistant,\n );\n return ChatMessage(\n role: role,\n text: (json['text'] ?? '').toString(),\n time: (json['time'] ?? '').toString(),\n );\n }\n}\n\nclass ModelProvider {\n const ModelProvider({\n required this.id,\n required this.name,\n required this.color,\n required this.icon,\n });\n\n final String id;\n final String name;\n final Color color;\n final String icon;\n}\n\nclass ProviderConfig {\n const ProviderConfig({\n this.baseUrl = '',\n this.apiPath = '',\n this.modelListPath = '',\n this.apiKey = '',\n this.extraHeaders = const {},\n this.model = '',\n this.availableModels = const [],\n this.improveNetworkCompatibility = false,\n this.reasoningEffort = 'very_high',\n });\n\n final String baseUrl;\n final String apiPath;\n final String modelListPath;\n final String apiKey;\n final Map<String, String> extraHeaders;\n final String model;\n final List<String> availableModels;\n final bool improveNetworkCompatibility;\n final String reasoningEffort;\n\n ProviderConfig copyWith({\n String? baseUrl,\n String? apiPath,\n String? modelListPath,\n String? apiKey,\n Map<String, String>? extraHeaders,\n String? model,\n List<String>? availableModels,\n bool? improveNetworkCompatibility,\n String? reasoningEffort,\n }) {\n return ProviderConfig(\n baseUrl: baseUrl ?? this.baseUrl,\n apiPath: apiPath ?? this.apiPath,\n modelListPath: modelListPath ?? this.modelListPath,\n apiKey: apiKey ?? this.apiKey,\n extraHeaders: extraHeaders ?? this.extraHeaders,\n model: model ?? this.model,\n availableModels: availableModels ?? this.availableModels,\n improveNetworkCompatibility:\n improveNetworkCompatibility ?? this.improveNetworkCompatibility,\n reasoningEffort: reasoningEffort ?? this.reasoningEffort,\n );\n }\n\n Map<String, dynamic> toJson() {\n return <String, dynamic>{\n 'baseUrl': baseUrl,\n 'apiPath': apiPath,\n 'modelListPath': modelListPath,\n 'apiKey': apiKey,\n 'extraHeaders': extraHeaders,\n 'model': model,\n 'availableModels': availableModels,\n 'improveNetworkCompatibility': improveNetworkCompatibility,\n 'reasoningEffort': reasoningEffort,\n };\n }\n\n static ProviderConfig fromJson(Map<String, dynamic> json) {\n final rawModels = json['availableModels'];\n final rawHeaders = json['extraHeaders'];\n return ProviderConfig(\n baseUrl: (json['baseUrl'] ?? '').toString(),\n apiPath: (json['apiPath'] ?? '').toString(),\n modelListPath: (json['modelListPath'] ?? '').toString(),\n apiKey: (json['apiKey'] ?? '').toString(),\n extraHeaders: rawHeaders is Map\n ? rawHeaders.map(\n (key, value) => MapEntry(key.toString(), value.toString()),\n )\n : const {},\n model: (json['model'] ?? '').toString(),\n availableModels: rawModels is List\n ? rawModels.map((item) => item.toString()).toList()\n : const [],\n improveNetworkCompatibility: json['improveNetworkCompatibility'] == true,\n reasoningEffort: (json['reasoningEffort'] ?? 'very_high').toString(),\n );\n }\n}\n\nclass ApiConnectionProfile {\n const ApiConnectionProfile({\n required this.id,\n required this.name,\n required this.providerId,\n required this.baseUrl,\n this.apiPath = '',\n this.modelListPath = '',\n required this.apiKey,\n this.extraHeaders = const {},\n required this.model,\n this.availableModels = const [],\n this.improveNetworkCompatibility = false,\n this.modelDisplayName = '',\n this.modelType = 'chat',\n this.inputModes = const ['text'],\n this.outputModes = const ['text'],\n this.capabilityTools = false,\n this.capabilityReasoning = false,\n this.reasoningEffort = 'very_high',\n });\n\n final String id;\n final String name;\n final String providerId;\n final String baseUrl;\n final String apiPath;\n final String modelListPath;\n final String apiKey;\n final Map<String, String> extraHeaders;\n final String model;\n final List<String> availableModels;\n final bool improveNetworkCompatibility;\n final String modelDisplayName;\n final String modelType;\n final List<String> inputModes;\n final List<String> outputModes;\n final bool capabilityTools;\n final bool capabilityReasoning;\n final String reasoningEffort;\n\n ProviderConfig toConfig() {\n return ProviderConfig(\n baseUrl: baseUrl,\n apiPath: apiPath,\n modelListPath: modelListPath,\n apiKey: apiKey,\n extraHeaders: extraHeaders,\n model: model,\n availableModels: availableModels,\n improveNetworkCompatibility: improveNetworkCompatibility,\n reasoningEffort: reasoningEffort,\n );\n }\n\n ApiConnectionProfile copyWith({\n String? id,\n String? name,\n String? providerId,\n String? baseUrl,\n String? apiPath,\n String? modelListPath,\n String? apiKey,\n Map<String, String>? extraHeaders,\n String? model,\n List<String>? availableModels,\n bool? improveNetworkCompatibility,\n String? modelDisplayName,\n String? modelType,\n List<String>? inputModes,\n List<String>? outputModes,\n bool? capabilityTools,\n bool? capabilityReasoning,\n String? reasoningEffort,\n }) {\n return ApiConnectionProfile(\n id: id ?? this.id,\n name: name ?? this.name,\n providerId: providerId ?? this.providerId,\n baseUrl: baseUrl ?? this.baseUrl,\n apiPath: apiPath ?? this.apiPath,\n modelListPath: modelListPath ?? this.modelListPath,\n apiKey: apiKey ?? this.apiKey,\n extraHeaders: extraHeaders ?? this.extraHeaders,\n model: model ?? this.model,\n availableModels: availableModels ?? this.availableModels,\n improveNetworkCompatibility:\n improveNetworkCompatibility ?? this.improveNetworkCompatibility,\n modelDisplayName: modelDisplayName ?? this.modelDisplayName,\n modelType: modelType ?? this.modelType,\n inputModes: inputModes ?? this.inputModes,\n outputModes: outputModes ?? this.outputModes,\n capabilityTools: capabilityTools ?? this.capabilityTools,\n capabilityReasoning: capabilityReasoning ?? this.capabilityReasoning,\n reasoningEffort: reasoningEffort ?? this.reasoningEffort,\n );\n }\n\n Map<String, dynamic> toJson() {\n return <String, dynamic>{\n 'id': id,\n 'name': name,\n 'providerId': providerId,\n 'baseUrl': baseUrl,\n 'apiPath': apiPath,\n 'modelListPath': modelListPath,\n 'apiKey': apiKey,\n 'extraHeaders': extraHeaders,\n 'model': model,\n 'availableModels': availableModels,\n 'improveNetworkCompatibility': improveNetworkCompatibility,\n 'modelDisplayName': modelDisplayName,\n 'modelType': modelType,\n 'inputModes': inputModes,\n 'outputModes': outputModes,\n 'capabilityTools': capabilityTools,\n 'capabilityReasoning': capabilityReasoning,\n 'reasoningEffort': reasoningEffort,\n };\n }\n\n static ApiConnectionProfile fromJson(Map<String, dynamic> json) {\n final rawModels = json['availableModels'];\n final rawHeaders = json['extraHeaders'];\n final rawInputModes = json['inputModes'];\n final rawOutputModes = json['outputModes'];\n final parsedInputModes = rawInputModes is List\n ? rawInputModes.map((item) => item.toString()).toList()\n : const <String>[];\n final parsedOutputModes = rawOutputModes is List\n ? rawOutputModes.map((item) => item.toString()).toList()\n : const <String>[];\n return ApiConnectionProfile(\n id: (json['id'] ?? '').toString(),\n name: (json['name'] ?? '').toString(),\n providerId: (json['providerId'] ?? 'openai').toString(),\n baseUrl: (json['baseUrl'] ?? '').toString(),\n apiPath: (json['apiPath'] ?? '').toString(),\n modelListPath: (json['modelListPath'] ?? '').toString(),\n apiKey: (json['apiKey'] ?? '').toString(),\n extraHeaders: rawHeaders is Map\n ? rawHeaders.map(\n (key, value) => MapEntry(key.toString(), value.toString()),\n )\n : const {},\n model: (json['model'] ?? '').toString(),\n availableModels: rawModels is List\n ? rawModels.map((item) => item.toString()).toList()\n : const [],\n improveNetworkCompatibility: json['improveNetworkCompatibility'] == true,\n modelDisplayName: (json['modelDisplayName'] ?? '').toString(),\n modelType: (json['modelType'] ?? 'chat').toString(),\n inputModes: parsedInputModes.isEmpty ? const ['text'] : parsedInputModes,\n outputModes: parsedOutputModes.isEmpty\n ? const ['text']\n : parsedOutputModes,\n capabilityTools: json['capabilityTools'] == true,\n capabilityReasoning: json['capabilityReasoning'] == true,\n reasoningEffort: (json['reasoningEffort'] ?? 'very_high').toString(),\n );\n }\n}\n\nclass ProjectFileSnippet {\n const ProjectFileSnippet({\n required this.path,\n required this.absolutePath,\n required this.preview,\n required this.sizeBytes,\n required this.isBinary,\n });\n\n final String path;\n final String absolutePath;\n final String preview;\n final int sizeBytes;\n final bool isBinary;\n}\n\nclass ProviderGuide {\n const ProviderGuide({\n required this.baseUrl,\n required this.auth,\n required this.modelListPath,\n required this.docsUrl,\n required this.note,\n this.supportsAutoFetch = true,\n });\n\n final String baseUrl;\n final String auth;\n final String modelListPath;\n final String docsUrl;\n final String note;\n final bool supportsAutoFetch;\n}\n\nconst List<ModelProvider> kProviders = [\n ModelProvider(\n id: 'openai',\n name: 'OpenAI',\n color: Color(0xFF111111),\n icon: 'OA',\n ),\n ModelProvider(\n id: 'openai_responses',\n name: 'OpenAI (Responses)',\n color: Color(0xFF202020),\n icon: 'OR',\n ),\n ModelProvider(\n id: 'gemini',\n name: 'Gemini',\n color: Color(0xFF2D7FF9),\n icon: 'GM',\n ),\n ModelProvider(\n id: 'claude',\n name: 'Claude',\n color: Color(0xFFDE8454),\n icon: 'CL',\n ),\n ModelProvider(\n id: 'deepseek',\n name: 'DeepSeek',\n color: Color(0xFF4C6DF6),\n icon: 'DS',\n ),\n ModelProvider(\n id: 'siliconflow',\n name: '硅基流动',\n color: Color(0xFF6D35FF),\n icon: 'SF',\n ),\n ModelProvider(\n id: 'openrouter',\n name: 'OpenRouter',\n color: Color(0xFF111111),\n icon: 'OR',\n ),\n ModelProvider(\n id: 'ollama',\n name: 'Ollama',\n color: Color(0xFFE8E8ED),\n icon: 'OL',\n ),\n ModelProvider(\n id: 'lmstudio',\n name: 'LM Studio',\n color: Color(0xFF4B41D4),\n icon: 'LM',\n ),\n ModelProvider(\n id: 'azure_openai',\n name: 'Azure OpenAI',\n color: Color(0xFF111111),\n icon: 'AZ',\n ),\n ModelProvider(id: 'groq', name: 'Groq', color: Color(0xFF111111), icon: 'GQ'),\n ModelProvider(id: 'xai', name: 'xAI', color: Color(0xFF111111), icon: 'XI'),\n ModelProvider(\n id: 'mistral',\n name: 'Mistral AI',\n color: Color(0xFFF2A53B),\n icon: 'MS',\n ),\n ModelProvider(\n id: 'perplexity',\n name: 'Perplexity',\n color: Color(0xFF111111),\n icon: 'PP',\n ),\n ModelProvider(\n id: 'volcano',\n name: '火山引擎',\n color: Color(0xFF4C6DF6),\n icon: 'VE',\n ),\n ModelProvider(\n id: 'chatglm',\n name: '智谱 BigModel',\n color: Color(0xFF4C6DF6),\n icon: 'GL',\n ),\n ModelProvider(id: 'custom', name: '自定义', color: Color(0xFF355273), icon: '自'),\n];\n\nconst Map<String, ProviderGuide> kProviderGuides = {\n 'openai': ProviderGuide(\n baseUrl: 'https://api.openai.com/v1',\n auth: 'Authorization: Bearer <OPENAI_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n note: '官方模型列表接口 GET /v1/models;建议优先使用 Responses API 完成对话调用。',\n ),\n 'openai_responses': ProviderGuide(\n baseUrl: 'https://api.openai.com/v1',\n auth: 'Authorization: Bearer <OPENAI_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n note: '同 OpenAI,适合以 Responses API 为主的接入方式。',\n ),\n 'gemini': ProviderGuide(\n baseUrl: 'https://generativelanguage.googleapis.com/v1beta',\n auth: 'x-goog-api-key: <GEMINI_API_KEY>',\n modelListPath: 'GET /models (Header 或 ?key=)',\n docsUrl: 'https://ai.google.dev/gemini-api/docs/models',\n note: '模型列表返回字段常见为 models[].name,例如 models/gemini-2.5-pro。',\n ),\n 'claude': ProviderGuide(\n baseUrl: 'https://api.anthropic.com',\n auth: 'x-api-key + anthropic-version',\n modelListPath: '/v1/models',\n docsUrl: 'https://docs.anthropic.com/en/api/models-list',\n note: 'Anthropic 原生 API 要求 anthropic-version 请求头,模型列表为 GET /v1/models。',\n ),\n 'deepseek': ProviderGuide(\n baseUrl: 'https://api.deepseek.com',\n auth: 'Authorization: Bearer <DEEPSEEK_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://api-docs.deepseek.com/api/list-models',\n note: '兼容 OpenAI 协议;官方同时说明 /v1 仅是兼容层,与模型版本无关。',\n ),\n 'siliconflow': ProviderGuide(\n baseUrl: 'https://api.siliconflow.cn/v1',\n auth: 'Authorization: Bearer <SILICONFLOW_API_KEY>',\n modelListPath: '/models',\n docsUrl:\n 'https://docs.siliconflow.cn/en/api-reference/models/get-model-list',\n note: '支持 type/sub_type 过滤模型。',\n ),\n 'openrouter': ProviderGuide(\n baseUrl: 'https://openrouter.ai/api/v1',\n auth: 'Authorization: Bearer <OPENROUTER_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://openrouter.ai/docs/api-reference/models/get-models',\n note: '可选 HTTP-Referer 与 X-Title 请求头用于应用归属与统计。',\n ),\n 'ollama': ProviderGuide(\n baseUrl: 'http://localhost:11434/api',\n auth: '本地默认无需鉴权;云端可 Bearer',\n modelListPath: '/tags',\n docsUrl: 'https://docs.ollama.com/api/tags',\n note: '本地常用 /api/tags 获取模型列表。',\n ),\n 'lmstudio': ProviderGuide(\n baseUrl: 'http://localhost:1234/v1',\n auth: '通常可用任意占位 key(如 lm-studio)',\n modelListPath: '/models',\n docsUrl: 'https://lmstudio.ai/docs/app/api/openai-compat',\n note: 'OpenAI 兼容接口,支持 /v1/models。',\n ),\n 'azure_openai': ProviderGuide(\n baseUrl: 'https://<resource>.openai.azure.com',\n auth: 'api-key: <AZURE_OPENAI_KEY>',\n modelListPath: '/openai/v1/models?api-version=preview',\n docsUrl:\n 'https://learn.microsoft.com/en-us/azure/foundry/openai/reference-preview',\n note: '官方预览文档包含 GET /openai/v1/models;聊天调用常用 deployment-name。',\n ),\n 'groq': ProviderGuide(\n baseUrl: 'https://api.groq.com/openai/v1',\n auth: 'Authorization: Bearer <GROQ_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://console.groq.com/docs/api-reference',\n note: 'OpenAI 兼容接口;模型列表走 /openai/v1/models。',\n ),\n 'xai': ProviderGuide(\n baseUrl: 'https://api.x.ai',\n auth: 'Authorization: Bearer <XAI_API_KEY>',\n modelListPath: '/v1/models',\n docsUrl: 'https://docs.x.ai/developers/api-reference/models',\n note: '官方全局入口为 api.x.ai,鉴权使用 Bearer Token。',\n ),\n 'mistral': ProviderGuide(\n baseUrl: 'https://api.mistral.ai/v1',\n auth: 'Authorization: Bearer <MISTRAL_API_KEY>',\n modelListPath: '/models',\n docsUrl: 'https://docs.mistral.ai/api/endpoint/models',\n note: '官方模型列表接口为 GET /v1/models。',\n ),\n 'perplexity': ProviderGuide(\n baseUrl: 'https://api.perplexity.ai',\n auth: 'Authorization: Bearer <PERPLEXITY_API_KEY>',\n modelListPath: '建议按文档模型页手动选择',\n docsUrl: 'https://docs.perplexity.ai/docs/agent-api/openai-compatibility',\n note: '官方同时给出 OpenAI 兼容方式,基地址在不同 API 版本文档中可能不同(v1/v2)。',\n supportsAutoFetch: false,\n ),\n 'volcano': ProviderGuide(\n baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',\n auth: 'Authorization: Bearer <ARK_API_KEY>',\n modelListPath: '控制台模型列表 / 固定 Model ID',\n docsUrl: 'https://www.volcengine.com/docs/82379/1338552',\n note: '火山方舟支持 API Key + Response API;模型 ID 通常从控制台获取。',\n supportsAutoFetch: false,\n ),\n 'chatglm': ProviderGuide(\n baseUrl: 'https://open.bigmodel.cn/api/paas/v4',\n auth: 'Authorization: Bearer <BIGMODEL_API_KEY>',\n modelListPath: '模型概览页 / 固定 Model ID',\n docsUrl: 'https://docs.bigmodel.cn/api-reference',\n note: '智谱 BigModel 文档提供统一鉴权与接口说明,模型通常按文档/控制台选择。',\n supportsAutoFetch: false,\n ),\n 'custom': ProviderGuide(\n baseUrl: '',\n auth: '按目标平台要求配置',\n modelListPath: '按目标平台定义',\n docsUrl: 'https://platform.openai.com/docs/api-reference/models/list',\n note: '自定义供应商可按 OpenAI 兼容模式接入。',\n supportsAutoFetch: false,\n ),\n};\n"}}}} |