refactor: reorganize imports and update type references across services

- Updated import paths for types and utilities in config-service, menu-service, script-execution-service, script-store-service, and window-service to reflect new structure.
- Moved utility functions like debounce and cloneDeep to shared utilities.
- Created new runtime and script types files to centralize type definitions.
- Removed deprecated task-types and locale messages files.
- Updated constants to use shared definitions and added new placeholders for providers.
- Enhanced provider type information with additional placeholders for different languages.
This commit is contained in:
duanshuwen
2026-04-21 23:25:51 +08:00
parent 97a956ffe8
commit 721344883f
24 changed files with 181 additions and 670 deletions

View File

@@ -1,4 +1,5 @@
export enum IPC_EVENTS {
HOST_API_FETCH = 'hostapi:fetch',
EXTERNAL_OPEN = 'external-open',
APP_SET_FRAMELESS = 'app:set-frameless',
APP_LOAD_PAGE = 'app:load-page',
@@ -120,3 +121,7 @@ export enum MESSAGE_ITEM_MENU_IDS {
DELETE = 'delete',
SELECT = 'select',
}
export const DEFAULT_THEME_MODE = 'system' as const;
export const DEFAULT_LANGUAGE = 'zh' as const;

View File

@@ -2,9 +2,13 @@ import {
DEFAULT_AGENT_ID,
DEFAULT_CHANNEL_ACCOUNT_ID,
DEFAULT_MAIN_SESSION_SUFFIX,
buildAgentSessionKey,
buildMainSessionKey,
buildChannelAccountOwnerKey,
normalizeAgentId,
normalizeChannelAccountId,
normalizeChannelType,
normalizeSessionSuffix,
parseChannelAccountOwnerKey,
resolveChannelAccountOwner,
type AgentSummary,
@@ -29,27 +33,6 @@ export interface ParsedSessionKey {
isAgentSession: boolean;
}
export function normalizeAgentId(value: string | null | undefined): string {
const normalized = String(value ?? '').trim().toLowerCase();
return normalized || DEFAULT_AGENT_ID;
}
export function normalizeSessionSuffix(value: string | null | undefined): string {
const normalized = String(value ?? '').trim().toLowerCase();
return normalized || DEFAULT_MAIN_SESSION_SUFFIX;
}
export function buildAgentSessionKey(agentId: string, sessionId: string): string {
return `agent:${normalizeAgentId(agentId)}:${normalizeSessionSuffix(sessionId)}`;
}
export function buildMainSessionKey(
agentId: string,
sessionId = DEFAULT_MAIN_SESSION_SUFFIX,
): string {
return buildAgentSessionKey(agentId, sessionId);
}
export function parseSessionKey(sessionKey: string): ParsedSessionKey {
const trimmed = String(sessionKey ?? '').trim();
@@ -97,9 +80,13 @@ export {
DEFAULT_AGENT_ID,
DEFAULT_CHANNEL_ACCOUNT_ID,
DEFAULT_MAIN_SESSION_SUFFIX,
buildAgentSessionKey,
buildMainSessionKey,
buildChannelAccountOwnerKey,
normalizeAgentId,
normalizeChannelAccountId,
normalizeChannelType,
normalizeSessionSuffix,
parseChannelAccountOwnerKey,
resolveChannelAccountOwner,
};

View File

@@ -58,6 +58,8 @@ export interface ProviderTypeInfo {
name: string;
icon: string;
placeholder: string;
placeholderZh?: string;
placeholderTh?: string;
model?: string;
requiresApiKey: boolean;
defaultBaseUrl?: string;
@@ -124,7 +126,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'anthropic',
name: 'Anthropic',
icon: 'A',
icon: '🤖',
placeholder: 'sk-ant-api03-...',
model: 'Claude',
requiresApiKey: true,
@@ -133,7 +135,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'openai',
name: 'OpenAI',
icon: 'O',
icon: '💚',
placeholder: 'sk-proj-...',
model: 'GPT',
requiresApiKey: true,
@@ -148,7 +150,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'google',
name: 'Google',
icon: 'G',
icon: '🔷',
placeholder: 'AIza...',
model: 'Gemini',
requiresApiKey: true,
@@ -163,7 +165,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'openrouter',
name: 'OpenRouter',
icon: 'R',
icon: '🌐',
placeholder: 'sk-or-v1-...',
model: 'Multi-Model',
requiresApiKey: true,
@@ -175,7 +177,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'minimax-portal-cn',
name: 'MiniMax (CN)',
icon: 'M',
icon: '☁️',
placeholder: 'sk-...',
model: 'MiniMax',
requiresApiKey: false,
@@ -192,7 +194,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'moonshot',
name: 'Moonshot (CN)',
icon: 'K',
icon: '🌙',
placeholder: 'sk-...',
model: 'Kimi',
requiresApiKey: true,
@@ -203,7 +205,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'siliconflow',
name: 'SiliconFlow (CN)',
icon: 'S',
icon: '🌊',
placeholder: 'sk-...',
model: 'Multi-Model',
requiresApiKey: true,
@@ -217,7 +219,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'deepseek',
name: 'DeepSeek',
icon: 'D',
icon: '🐋',
placeholder: 'sk-...',
model: 'DeepSeek',
requiresApiKey: true,
@@ -231,7 +233,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'minimax-portal',
name: 'MiniMax (Global)',
icon: 'M',
icon: '☁️',
placeholder: 'sk-...',
model: 'MiniMax',
requiresApiKey: false,
@@ -248,7 +250,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'modelstudio',
name: 'Model Studio',
icon: 'Q',
icon: '☁️',
placeholder: 'sk-...',
model: 'Qwen',
requiresApiKey: true,
@@ -264,7 +266,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'ark',
name: 'ByteDance Ark',
icon: 'B',
icon: 'A',
placeholder: 'your-ark-api-key',
model: 'Doubao',
requiresApiKey: true,
@@ -280,8 +282,10 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'ollama',
name: 'Ollama',
icon: 'L',
icon: '🦙',
placeholder: 'Not required',
placeholderZh: '无需填写',
placeholderTh: 'ไม่ต้องกรอก',
requiresApiKey: false,
defaultBaseUrl: 'http://localhost:11434/v1',
showBaseUrl: true,
@@ -291,8 +295,10 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
{
id: 'custom',
name: 'Custom',
icon: 'C',
icon: '⚙️',
placeholder: 'API key...',
placeholderZh: 'API Key...',
placeholderTh: 'API Key...',
requiresApiKey: true,
showBaseUrl: true,
showModelId: true,
@@ -329,6 +335,22 @@ export function getProviderDocsUrl(
return provider.docsUrl;
}
export function getProviderPlaceholder(
provider: Pick<ProviderTypeInfo, 'placeholder' | 'placeholderZh' | 'placeholderTh'> | undefined,
language: string,
): string | undefined {
if (!provider?.placeholder) {
return undefined;
}
if (language.startsWith('zh') && provider.placeholderZh) {
return provider.placeholderZh;
}
if (language.startsWith('th') && provider.placeholderTh) {
return provider.placeholderTh;
}
return provider.placeholder;
}
export function shouldShowProviderModelId(
provider: Pick<ProviderTypeInfo, 'showModelId' | 'showModelIdInDevModeOnly'> | undefined,
devModeUnlocked: boolean,

View File

@@ -1,53 +0,0 @@
export interface ScriptLastRun {
time: string;
success: boolean;
error?: string;
}
export interface AutomationScript {
id: string;
name: string;
description: string;
filename: string;
enabled: boolean;
channel: string;
createdAt: string;
updatedAt: string;
code?: string;
lastRun?: ScriptLastRun;
}
export interface ScriptSaveInput {
id?: string;
name: string;
description: string;
code: string;
channel: string;
enabled: boolean;
}
export interface ScriptExecutionResult {
success: boolean;
exitCode: number | null;
stdoutTail: string;
stderrTail: string;
error?: string;
}
export type ScriptRecordingStatus = 'idle' | 'recording' | 'stopped';
export interface ScriptMetaItem {
id: string;
name: string;
description: string;
filename: string;
enabled: boolean;
channel: string;
createdAt: string;
updatedAt: string;
lastRun?: ScriptLastRun;
}
export interface ScriptsMeta {
scripts: ScriptMetaItem[];
}

View File

@@ -1,40 +0,0 @@
export type SubTaskStatus = 'pending' | 'running' | 'success' | 'failed';
export interface SubTask {
id: string;
taskId: string;
scriptId: string;
name: string;
status: SubTaskStatus;
progress: number;
message: string;
stdoutTail: string;
stderrTail: string;
error?: string;
startedAt: string;
completedAt?: string;
}
export type TaskStatus = 'pending' | 'running' | 'success' | 'partial_failed' | 'failed';
export interface Task {
id: string;
title: string;
operation: 'open' | 'close';
roomType: string;
dateRange: [string, string];
status: TaskStatus;
subTasks: SubTask[];
roomList: any[];
createdAt: string;
updatedAt: string;
}
export interface TaskProgressPayload {
taskId: string;
subTaskId: string;
progress?: number;
message?: string;
stdoutTail?: string;
stderrTail?: string;
}

View File

@@ -1,40 +0,0 @@
import type { Task } from './task-types';
import { CONFIG_KEYS, WINDOW_NAMES } from './constants';
export type ThemeMode = 'dark' | 'light' | 'system';
export type WindowNames = `${WINDOW_NAMES}`;
export type ConfigKeys = `${CONFIG_KEYS}`;
export interface IConfig {
[CONFIG_KEYS.THEME_MODE]: ThemeMode;
[CONFIG_KEYS.PRIMARY_COLOR]: string;
[CONFIG_KEYS.LANGUAGE]: 'zh' | 'en';
[CONFIG_KEYS.FONT_SIZE]: number;
[CONFIG_KEYS.MINIMIZE_TO_TRAY]: boolean;
[CONFIG_KEYS.LAUNCH_AT_STARTUP]: boolean;
[CONFIG_KEYS.PROVIDER]?: string;
[CONFIG_KEYS.DEFAULT_MODEL]?: string | null;
[CONFIG_KEYS.AUTO_CHECK_UPDATE]?: boolean;
[CONFIG_KEYS.AUTO_DOWNLOAD_UPDATE]?: boolean;
[CONFIG_KEYS.GATEWAY_AUTO_START]?: boolean;
[CONFIG_KEYS.SELECTED_CHANNELS]: Array<{ id: string; channelName: string; channelUrl: string }>;
[CONFIG_KEYS.IMAGE_CACHE]: Array<[string, any]>;
[CONFIG_KEYS.TASK_LIST]?: Task[];
}
export interface Provider {
id: number;
name: string;
visible?: boolean;
title?: string;
type?: 'OpenAI';
openAISetting?: string;
createdAt: number;
updatedAt: number;
models: string[];
}
export interface OpenAISetting {
baseURL?: string;
apiKey?: string;
}

View File

@@ -1,33 +0,0 @@
export function debounce<T extends (...args: any[]) => any>(
fn: T,
delay: number,
): (...args: Parameters<T>) => void {
let timer: NodeJS.Timeout | null = null;
return function debounced(this: unknown, ...args: Parameters<T>) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
export function cloneDeep<T>(obj: T): T {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (Array.isArray(obj)) {
return obj.map((item) => cloneDeep(item)) as T;
}
const clone = Object.assign({}, obj);
for (const key in clone) {
if (Object.prototype.hasOwnProperty.call(clone, key)) {
clone[key] = cloneDeep(clone[key]);
}
}
return clone;
}