feat(core): improve byok editing (#15427)
fix #14287 fix #15359 fix #15424 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Redesigned workspace AI provider settings with connection testing, storage options, model selection, capability management, ordering, and custom endpoints. * AI chat model choices now adapt to the selected workspace and conversation route. * Added support for image-based AI requests. * **Bug Fixes** * Improved handling of unavailable or outdated model selections. * App configuration updates now reject overlapping paths and load deterministically. * **Tests** * Expanded coverage for provider models, AI chat scoping, image requests, and configuration validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -9,11 +9,34 @@ export class AppConfigModel extends BaseModel {
|
||||
async load(excludedKeys: string[] = []) {
|
||||
return this.db.appConfig.findMany({
|
||||
where: excludedKeys.length ? { id: { notIn: excludedKeys } } : undefined,
|
||||
orderBy: { id: 'asc' },
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional()
|
||||
async save(user: string, updates: Array<{ key: string; value: any }>) {
|
||||
await this.db
|
||||
.$executeRaw`SELECT pg_advisory_xact_lock(hashtextextended(${'app-config-paths'}, 0))`;
|
||||
const existing = await this.db.appConfig.findMany({
|
||||
select: { id: true },
|
||||
});
|
||||
const updateKeys = updates.map(update => update.key);
|
||||
for (const [index, key] of updateKeys.entries()) {
|
||||
const overlappingKey = [
|
||||
...existing.map(config => config.id),
|
||||
...updateKeys.slice(0, index),
|
||||
].find(
|
||||
candidate =>
|
||||
candidate !== key &&
|
||||
(candidate.startsWith(`${key}.`) || key.startsWith(`${candidate}.`))
|
||||
);
|
||||
if (overlappingKey) {
|
||||
throw new Error(
|
||||
`App config paths must not overlap: ${overlappingKey} and ${key}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return await Promise.allSettled(
|
||||
updates.map(async update => {
|
||||
return this.db.appConfig.upsert({
|
||||
|
||||
Reference in New Issue
Block a user