feat(agents, sessions): implement replace functionality for agent and session updates

This commit is contained in:
Vaayne
2025-09-19 11:13:05 +08:00
parent df1d4cd62b
commit 514b60f704
9 changed files with 97 additions and 46 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ export abstract class BaseService {
protected static db: LibSQLDatabase<typeof schema> | null = null
protected static isInitialized = false
protected static initializationPromise: Promise<void> | null = null
protected jsonFields: string[] = ['built_in_tools', 'mcps', 'configuration', 'accessible_paths']
protected jsonFields: string[] = ['built_in_tools', 'mcps', 'configuration', 'accessible_paths', 'allowed_tools']
/**
* Initialize database with retry logic and proper error handling
@@ -1,7 +1,8 @@
import path from 'node:path'
import { getDataPath } from '@main/utils'
import type {
import {
AgentBaseSchema,
AgentEntity,
CreateAgentRequest,
CreateAgentResponse,
@@ -111,7 +112,11 @@ export class AgentService extends BaseService {
return { agents, total: totalResult[0].count }
}
async updateAgent(id: string, updates: UpdateAgentRequest): Promise<UpdateAgentResponse | null> {
async updateAgent(
id: string,
updates: UpdateAgentRequest,
options: { replace?: boolean } = {}
): Promise<UpdateAgentResponse | null> {
this.ensureInitialized()
// Check if agent exists
@@ -126,18 +131,20 @@ export class AgentService extends BaseService {
const updateData: Partial<AgentRow> = {
updated_at: now
}
const replaceableFields = Object.keys(AgentBaseSchema.shape) as (keyof AgentRow)[]
const shouldReplace = options.replace ?? false
for (const field of replaceableFields) {
if (shouldReplace || Object.prototype.hasOwnProperty.call(serializedUpdates, field)) {
if (Object.prototype.hasOwnProperty.call(serializedUpdates, field)) {
const value = serializedUpdates[field as keyof typeof serializedUpdates]
;(updateData as Record<string, unknown>)[field] = value ?? null
} else if (shouldReplace) {
;(updateData as Record<string, unknown>)[field] = null
}
}
}
// Only update fields that are provided
if (serializedUpdates.name !== undefined) updateData.name = serializedUpdates.name
if (serializedUpdates.description !== undefined) updateData.description = serializedUpdates.description
if (serializedUpdates.instructions !== undefined) updateData.instructions = serializedUpdates.instructions
if (serializedUpdates.model !== undefined) updateData.model = serializedUpdates.model
if (serializedUpdates.plan_model !== undefined) updateData.plan_model = serializedUpdates.plan_model
if (serializedUpdates.small_model !== undefined) updateData.small_model = serializedUpdates.small_model
if (serializedUpdates.mcps !== undefined) updateData.mcps = serializedUpdates.mcps
if (serializedUpdates.configuration !== undefined) updateData.configuration = serializedUpdates.configuration
if (serializedUpdates.accessible_paths !== undefined)
updateData.accessible_paths = serializedUpdates.accessible_paths
await this.database.update(agentsTable).set(updateData).where(eq(agentsTable.id, id))
return await this.getAgent(id)
}
@@ -1,11 +1,12 @@
import type {
AgentEntity,
AgentSessionEntity,
CreateSessionRequest,
CreateSessionResponse,
GetAgentSessionResponse,
ListOptions,
UpdateSessionRequest
import {
AgentBaseSchema,
type AgentEntity,
type AgentSessionEntity,
type CreateSessionRequest,
type CreateSessionResponse,
type GetAgentSessionResponse,
type ListOptions,
type UpdateSessionRequest
} from '@types'
import { and, count, eq, type SQL } from 'drizzle-orm'
@@ -149,7 +150,11 @@ export class SessionService extends BaseService {
return { sessions, total }
}
async updateSession(agentId: string, id: string, updates: UpdateSessionRequest): Promise<GetAgentSessionResponse | null> {
async updateSession(
agentId: string,
id: string,
updates: UpdateSessionRequest
): Promise<GetAgentSessionResponse | null> {
this.ensureInitialized()
// Check if session exists
@@ -167,19 +172,14 @@ export class SessionService extends BaseService {
const updateData: Partial<SessionRow> = {
updated_at: now
}
const replaceableFields = Object.keys(AgentBaseSchema.shape) as (keyof SessionRow)[]
// Only update fields that are provided
if (serializedUpdates.name !== undefined) updateData.name = serializedUpdates.name
if (serializedUpdates.model !== undefined) updateData.model = serializedUpdates.model
if (serializedUpdates.plan_model !== undefined) updateData.plan_model = serializedUpdates.plan_model
if (serializedUpdates.small_model !== undefined) updateData.small_model = serializedUpdates.small_model
if (serializedUpdates.mcps !== undefined) updateData.mcps = serializedUpdates.mcps
if (serializedUpdates.configuration !== undefined) updateData.configuration = serializedUpdates.configuration
if (serializedUpdates.accessible_paths !== undefined)
updateData.accessible_paths = serializedUpdates.accessible_paths
for (const field of replaceableFields) {
if (Object.prototype.hasOwnProperty.call(serializedUpdates, field)) {
const value = serializedUpdates[field as keyof typeof serializedUpdates]
;(updateData as Record<string, unknown>)[field] = value ?? null
}
}
await this.database.update(sessionsTable).set(updateData).where(eq(sessionsTable.id, id))