Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 26 additions & 53 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ export class AgentsController {
throw new BadRequestException('Agent name produces an empty slug');
}
const displayName = body.name.trim();
await this.aggregation.renameAgent(user.id, agentName, slug, displayName);
await this.aggregation.renameAgent(
user.id,
agentName,
slug,
displayName,
body.request_timeout_ms,
);
return { renamed: true, name: slug, display_name: displayName };
}

Expand Down
13 changes: 11 additions & 2 deletions packages/backend/src/analytics/services/aggregation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ export class AggregationService {
currentName: string,
newName: string,
displayName?: string,
requestTimeoutMs?: number,
): Promise<void> {
const agent = await this.agentRepo
.createQueryBuilder('a')
Expand All @@ -261,13 +262,20 @@ export class AggregationService {
throw new NotFoundException(`Agent "${currentName}" not found`);
}

// If only display_name changes (same slug), short-circuit
// If only display_name or timeout changes (same slug), short-circuit
if (newName === currentName) {
const updates: Record<string, unknown> = {};
if (displayName !== undefined) {
updates.display_name = displayName;
}
if (requestTimeoutMs !== undefined) {
updates.request_timeout_ms = requestTimeoutMs;
}
if (Object.keys(updates).length > 0) {
await this.agentRepo
.createQueryBuilder()
.update('agents')
.set({ display_name: displayName })
.set(updates)
.where('id = :id', { id: agent.id })
.execute();
}
Expand All @@ -288,6 +296,7 @@ export class AggregationService {
await this.dataSource.transaction(async (manager) => {
const agentUpdate: Record<string, unknown> = { name: newName };
if (displayName !== undefined) agentUpdate['display_name'] = displayName;
if (requestTimeoutMs !== undefined) agentUpdate['request_timeout_ms'] = requestTimeoutMs;

await manager
.createQueryBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ export class TimeseriesQueriesService {
total_cost: Number(stats?.['total_cost'] ?? 0),
total_tokens: Number(stats?.['total_tokens'] ?? 0),
sparkline: sparkMap.get(name) ?? [],
request_timeout_ms: a.request_timeout_ms,
};
});
}
Expand Down
20 changes: 18 additions & 2 deletions packages/backend/src/common/dto/rename-agent.dto.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import { IsString, IsNotEmpty, MinLength, MaxLength, Matches } from 'class-validator';
import {
IsString,
IsNotEmpty,
MinLength,
MaxLength,
Matches,
IsOptional,
IsNumber,
Min,
} from 'class-validator';

export class RenameAgentDto {
@IsString()
@IsNotEmpty()
@MinLength(1)
@MaxLength(100)
@Matches(/^[a-zA-Z0-9 _-]+$/, { message: 'Agent name must contain only letters, numbers, spaces, dashes, and underscores' })
@Matches(/^[a-zA-Z0-9 _-]+$/, {
message: 'Agent name must contain only letters, numbers, spaces, dashes, and underscores',
})
name!: string;

@IsOptional()
@IsNumber()
@Min(1000)
request_timeout_ms?: number;
}
2 changes: 2 additions & 0 deletions packages/backend/src/database/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { AddModelsAgentIndex1773202787708 } from './migrations/1773202787708-Add
import { AddEmailProviderKeyPrefix1773300000000 } from './migrations/1773300000000-AddEmailProviderKeyPrefix';
import { AddProviderModelCache1773400000000 } from './migrations/1773400000000-AddProviderModelCache';
import { DropModelPricingTables1773500000000 } from './migrations/1773500000000-DropModelPricingTables';
import { AddAgentRequestTimeout1773600000000 } from './migrations/1773600000000-AddAgentRequestTimeout';

const entities = [
AgentMessage,
Expand Down Expand Up @@ -112,6 +113,7 @@ const migrations = [
AddEmailProviderKeyPrefix1773300000000,
AddProviderModelCache1773400000000,
DropModelPricingTables1773500000000,
AddAgentRequestTimeout1773600000000,
];

const isLocalMode = process.env['MANIFEST_MODE'] === 'local';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddAgentRequestTimeout1773600000000 implements MigrationInterface {
name = 'AddAgentRequestTimeout1773600000000';

public async up(queryRunner: QueryRunner): Promise<void> {
// Add request_timeout_ms column to agents table
await queryRunner.query(
`ALTER TABLE "agents" ADD COLUMN "request_timeout_ms" INTEGER DEFAULT NULL`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
// Remove request_timeout_ms column from agents table
await queryRunner.query(`ALTER TABLE "agents" DROP COLUMN "request_timeout_ms"`);
}
}
Loading
Loading