From 259f2157f67eaea6e28c703d82dd2db8d7297a97 Mon Sep 17 00:00:00 2001 From: icarus Date: Thu, 18 Sep 2025 18:21:52 +0800 Subject: [PATCH] refactor(agent): split AgentForm into BaseAgentForm and specific types Improve type safety by separating AgentForm into BaseAgentForm for shared fields and specific types for add/update operations. This better reflects the actual usage patterns in the API client and modal components. --- src/renderer/src/api/agent.ts | 15 ++++++--------- src/renderer/src/components/Popups/AgentModal.tsx | 8 ++++---- src/renderer/src/types/agent.ts | 12 ++++++++++-- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/renderer/src/api/agent.ts b/src/renderer/src/api/agent.ts index 5fe6dd99ca..a17802f4a9 100644 --- a/src/renderer/src/api/agent.ts +++ b/src/renderer/src/api/agent.ts @@ -1,6 +1,6 @@ import { formatAgentServerError } from '@renderer/utils' import { - AgentForm, + AddAgentForm, AgentServerErrorSchema, CreateAgentRequest, CreateAgentResponse, @@ -9,6 +9,7 @@ import { GetAgentResponseSchema, type ListAgentsResponse, ListAgentsResponseSchema, + UpdateAgentForm, UpdateAgentRequest, UpdateAgentResponse, UpdateAgentResponseSchema @@ -71,12 +72,10 @@ export class AgentApiClient { } } - public async createAgent(agent: AgentForm): Promise { + public async createAgent(agent: AddAgentForm): Promise { const url = this.agentPaths.base try { - const payload = { - ...agent - } satisfies CreateAgentRequest + const payload = agent satisfies CreateAgentRequest const response = await this.axios.post(url, payload) const data = CreateAgentResponseSchema.parse(response.data) return data @@ -105,12 +104,10 @@ export class AgentApiClient { } } - public async updateAgent(id: string, agent: Partial): Promise { + public async updateAgent(id: string, agent: UpdateAgentForm): Promise { const url = this.agentPaths.withId(id) try { - const payload = { - ...agent - } satisfies UpdateAgentRequest + const payload = agent satisfies UpdateAgentRequest const response = await this.axios.patch(url, payload) const data = UpdateAgentResponseSchema.parse(response.data) return data diff --git a/src/renderer/src/components/Popups/AgentModal.tsx b/src/renderer/src/components/Popups/AgentModal.tsx index c07aa94408..7f6d00b81c 100644 --- a/src/renderer/src/components/Popups/AgentModal.tsx +++ b/src/renderer/src/components/Popups/AgentModal.tsx @@ -21,7 +21,7 @@ import ClaudeIcon from '@renderer/assets/images/models/claude.png' import { useAgents } from '@renderer/hooks/agents/useAgents' import { useTimer } from '@renderer/hooks/useTimer' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' -import { AgentEntity, AgentForm, isAgentType } from '@renderer/types' +import { AgentEntity, AgentForm, BaseAgentForm, isAgentType } from '@renderer/types' import { uuid } from '@renderer/utils' import { ChangeEvent, FormEvent, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -44,7 +44,7 @@ interface AgentTypeOption extends Option { type ModelOption = Option -const buildAgentForm = (existing?: AgentEntity): AgentForm => ({ +const buildAgentForm = (existing?: AgentEntity): BaseAgentForm => ({ type: existing?.type ?? 'claude-code', name: existing?.name ?? 'Claude Code', description: existing?.description, @@ -162,7 +162,7 @@ export const AgentModal: React.FC = ({ agent, trigger, isOpen: _isOpen, o } setForm((prev) => ({ ...prev, - type: e.target.value as AgentForm['type'], + type: e.target.value as AgentType, name: newName })) }, @@ -229,7 +229,7 @@ export const AgentModal: React.FC = ({ agent, trigger, isOpen: _isOpen, o return } - let resultAgent: AgentEntity + let resultAgent: BaseAgentForm if (isEditing(agent)) { if (!agent) { throw new Error('Agent is required for editing mode') diff --git a/src/renderer/src/types/agent.ts b/src/renderer/src/types/agent.ts index d29e334953..25ad2272c9 100644 --- a/src/renderer/src/types/agent.ts +++ b/src/renderer/src/types/agent.ts @@ -118,8 +118,8 @@ export interface SessionMessageContent { // - mcps: Optional array of MCP (Model Control Protocol) tool IDs // - allowed_tools: Optional array of permitted tool IDs // - configuration: Optional agent settings (temperature, top_p, etc.) -export type AgentForm = { - type: AgentType +export interface BaseAgentForm { + // These fileds should be editable by user. name: string description?: string instructions?: string @@ -127,6 +127,14 @@ export type AgentForm = { accessible_paths: string[] } +export interface AddAgentForm extends BaseAgentForm { + type: AgentType +} + +export type UpdateAgentForm = Partial + +export type AgentForm = AddAgentForm | UpdateAgentForm + // ------------------------ // API Data Transfer Object // ------------------------