agentManagement.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import type { JsonValue } from '@shared/types'
  2. import { apiRequest } from './client'
  3. export interface CustomModelService {
  4. id: string
  5. name: string
  6. base_url: string
  7. model: string
  8. models: string[]
  9. context_length?: number
  10. discover_models: boolean
  11. has_api_key: boolean
  12. api_key_preview?: string
  13. is_current: boolean
  14. source?: string
  15. }
  16. export interface CustomModelServicesResponse {
  17. endpoints: CustomModelService[]
  18. current: { provider: string; model: string; base_url: string }
  19. ok?: boolean
  20. id?: string
  21. }
  22. export interface CustomModelServiceInput {
  23. id?: string
  24. name: string
  25. base_url: string
  26. model: string
  27. api_key?: string
  28. context_length?: number
  29. discover_models: boolean
  30. make_default: boolean
  31. models?: string[]
  32. }
  33. export interface ModelServiceValidation {
  34. ok: boolean
  35. reachable: boolean
  36. message: string
  37. models: string[]
  38. }
  39. export interface ModelCatalogProvider {
  40. slug: string
  41. name: string
  42. models: string[]
  43. isCurrent: boolean
  44. }
  45. export interface LegacyModelService extends CustomModelService {
  46. source: 'legacy'
  47. can_edit_api_key: boolean
  48. }
  49. export interface DuplexVoice {
  50. id: string
  51. name: string
  52. }
  53. export interface DuplexVoiceSettings {
  54. hasApiKey: boolean
  55. voices: DuplexVoice[]
  56. currentVoiceId: string
  57. updatedAt: number
  58. }
  59. function profileQuery(profile: string): string {
  60. return `?profile=${encodeURIComponent(profile)}`
  61. }
  62. export function listModelServices(profile: string): Promise<CustomModelServicesResponse> {
  63. return apiRequest(`/api/app/admin/model-services${profileQuery(profile)}`)
  64. }
  65. export async function listModelCatalog(profile: string): Promise<ModelCatalogProvider[]> {
  66. const payload = await apiRequest<{ providers?: unknown[] }>(`/api/app/models${profileQuery(profile)}`)
  67. return (payload.providers || []).flatMap(raw => {
  68. if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return []
  69. const provider = raw as Record<string, unknown>
  70. const slug = typeof provider.slug === 'string' ? provider.slug.trim() : ''
  71. if (!slug) return []
  72. return [{
  73. slug,
  74. name: typeof provider.name === 'string' && provider.name.trim() ? provider.name.trim() : slug,
  75. models: Array.isArray(provider.models) ? provider.models.map(String).map(item => item.trim()).filter(Boolean) : [],
  76. isCurrent: provider.is_current === true,
  77. }]
  78. })
  79. }
  80. export async function listLegacyModelServices(profile: string): Promise<LegacyModelService[]> {
  81. const response = await apiRequest<{ items?: LegacyModelService[] }>(`/api/app/admin/legacy-model-services${profileQuery(profile)}`)
  82. return response.items || []
  83. }
  84. export function saveLegacyModelService(profile: string, id: string, input: CustomModelServiceInput): Promise<void> {
  85. return apiRequest(`/api/app/admin/legacy-model-services/${encodeURIComponent(id)}${profileQuery(profile)}`, {
  86. method: 'PUT', body: input as unknown as JsonValue,
  87. })
  88. }
  89. export function saveModelService(profile: string, input: CustomModelServiceInput): Promise<CustomModelServicesResponse> {
  90. return apiRequest(`/api/app/admin/model-services${profileQuery(profile)}`, {
  91. method: 'POST', body: input as unknown as JsonValue,
  92. })
  93. }
  94. export function validateModelService(input: CustomModelServiceInput): Promise<ModelServiceValidation> {
  95. return apiRequest('/api/app/admin/model-services/validate', {
  96. method: 'POST', body: input as unknown as JsonValue, timeoutMs: 15_000,
  97. })
  98. }
  99. export function activateModelService(profile: string, id: string): Promise<void> {
  100. return apiRequest(`/api/app/admin/model-services/${encodeURIComponent(id)}/activate${profileQuery(profile)}`, {
  101. method: 'POST', body: {},
  102. })
  103. }
  104. export function deleteModelService(profile: string, id: string): Promise<void> {
  105. return apiRequest(`/api/app/admin/model-services/${encodeURIComponent(id)}${profileQuery(profile)}`, {
  106. method: 'DELETE', body: {},
  107. })
  108. }
  109. export function getDuplexVoiceSettings(): Promise<DuplexVoiceSettings> {
  110. return apiRequest('/api/app/admin/duplex-voice')
  111. }
  112. export function saveDuplexVoiceSettings(input: {
  113. apiKey?: string
  114. voices: DuplexVoice[]
  115. currentVoiceId: string
  116. }): Promise<DuplexVoiceSettings> {
  117. return apiRequest('/api/app/admin/duplex-voice', {
  118. method: 'PUT', body: input as unknown as JsonValue,
  119. })
  120. }