sa2kit 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{chunk-ZJLS5JU5.mjs → chunk-6KD4CD7O.mjs} +7 -16
  2. package/dist/chunk-6KD4CD7O.mjs.map +1 -0
  3. package/dist/chunk-GJVEYCS4.js +12 -0
  4. package/dist/chunk-GJVEYCS4.js.map +1 -0
  5. package/dist/chunk-PPV4IEWR.mjs +8 -0
  6. package/dist/chunk-PPV4IEWR.mjs.map +1 -0
  7. package/dist/{chunk-XPY45Y75.js → chunk-VVHFMAE7.js} +9 -21
  8. package/dist/chunk-VVHFMAE7.js.map +1 -0
  9. package/dist/common/aiApi/client/index.d.mts +66 -4
  10. package/dist/common/aiApi/client/index.d.ts +66 -4
  11. package/dist/common/aiApi/client/index.js +360 -15
  12. package/dist/common/aiApi/client/index.js.map +1 -1
  13. package/dist/common/aiApi/client/index.mjs +345 -11
  14. package/dist/common/aiApi/client/index.mjs.map +1 -1
  15. package/dist/common/aiApi/index.d.mts +2 -2
  16. package/dist/common/aiApi/index.d.ts +2 -2
  17. package/dist/common/aiApi/index.js +63 -62
  18. package/dist/common/aiApi/index.mjs +2 -1
  19. package/dist/common/aiApi/server/index.d.mts +1 -1
  20. package/dist/common/aiApi/server/index.d.ts +1 -1
  21. package/dist/common/aiApi/server/index.js +63 -62
  22. package/dist/common/aiApi/server/index.mjs +2 -1
  23. package/dist/index.d.mts +9 -1
  24. package/dist/index.d.ts +9 -1
  25. package/dist/index.js +3 -9
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +3 -9
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/{types-CiqMQ-uu.d.mts → types-DgbG0Of-.d.mts} +9 -1
  30. package/dist/{types-CiqMQ-uu.d.ts → types-DgbG0Of-.d.ts} +9 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-XPY45Y75.js.map +0 -1
  33. package/dist/chunk-ZJLS5JU5.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/common/aiApi/client/settingsCore.ts","../../../../src/common/aiApi/client/aiApiClient.ts","../../../../src/common/aiApi/client/fetchModels.ts","../../../../src/common/aiApi/client/hooks/useAiTask.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { AiClientSettings, AudioStrategy } from '../types';\n\nexport interface AiApiSettings {\n apiKey: string;\n baseUrl: string;\n visionModel: string;\n textModel?: string;\n audioModel?: string;\n audioStrategy?: AudioStrategy;\n}\n\nexport const DEFAULT_AI_API_SETTINGS: AiApiSettings = {\n apiKey: '',\n baseUrl: 'https://api.openai.com/v1',\n visionModel: 'gpt-4o-mini',\n textModel: 'gpt-4o-mini',\n audioModel: 'whisper-1',\n audioStrategy: 'auto',\n};\n\nexport const AI_API_SETTINGS_STORAGE_KEY = 'ai-api-settings';\n\nexport function loadAiApiSettings(storageKey = AI_API_SETTINGS_STORAGE_KEY): AiApiSettings {\n if (typeof window === 'undefined') return DEFAULT_AI_API_SETTINGS;\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return DEFAULT_AI_API_SETTINGS;\n return { ...DEFAULT_AI_API_SETTINGS, ...JSON.parse(raw) };\n } catch {\n return DEFAULT_AI_API_SETTINGS;\n }\n}\n\nexport function saveAiApiSettings(\n settings: AiApiSettings,\n storageKey = AI_API_SETTINGS_STORAGE_KEY\n): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(storageKey, JSON.stringify(settings));\n}\n\nexport function toClientSettings(settings: AiApiSettings): AiClientSettings | undefined {\n const client: AiClientSettings = {};\n if (settings.apiKey.trim()) client.apiKey = settings.apiKey.trim();\n if (settings.baseUrl.trim()) client.baseUrl = settings.baseUrl.trim();\n const visionModel = settings.visionModel.trim();\n const textModel = settings.textModel?.trim() || visionModel;\n const audioModel = settings.audioModel?.trim();\n if (visionModel) client.visionModel = visionModel;\n if (textModel) client.textModel = textModel;\n if (audioModel) client.audioModel = audioModel;\n if (settings.audioStrategy) client.audioStrategy = settings.audioStrategy;\n return Object.keys(client).length > 0 ? client : undefined;\n}\n\nexport function pickClientSettingsFromStorage(\n storageKey = AI_API_SETTINGS_STORAGE_KEY\n): AiClientSettings | undefined {\n return toClientSettings(loadAiApiSettings(storageKey));\n}\n","import type { AiApiResponse, AiApiRunRequest, AiClientSettings } from '../types';\nimport { pickClientSettingsFromStorage } from './settingsCore';\n\nexport class AiApiClientError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n public readonly response?: AiApiResponse\n ) {\n super(message);\n this.name = 'AiApiClientError';\n }\n}\n\nexport interface AiApiClientOptions {\n /** 默认 POST /api/ai/run,宿主应用可覆盖 */\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * 通过 HTTP 调用宿主暴露的 AI 任务入口(如 Next.js route)。\n * 连接配置可通过请求体 clientSettings 传入,或从 localStorage 读取。\n */\nexport async function runAiTask<TInput, TOutput>(\n taskId: string,\n input: TInput,\n options?: {\n signal?: AbortSignal;\n clientSettings?: AiClientSettings;\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n }\n): Promise<AiApiResponse<TOutput>> {\n const fetchFn = options?.fetchImpl ?? fetch;\n const endpoint = options?.runEndpoint ?? '/api/ai/run';\n const clientSettings = options?.clientSettings ?? pickClientSettingsFromStorage();\n\n const payload: AiApiRunRequest<TInput> = {\n taskId,\n input,\n ...(clientSettings ? { clientSettings } : {}),\n };\n\n const response = await fetchFn(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n signal: options?.signal,\n });\n\n const data = (await response.json()) as AiApiResponse<TOutput>;\n return data;\n}\n\nexport async function runAiTaskOrThrow<TInput, TOutput>(\n taskId: string,\n input: TInput,\n options?: {\n signal?: AbortSignal;\n clientSettings?: AiClientSettings;\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n }\n): Promise<TOutput> {\n const result = await runAiTask<TInput, TOutput>(taskId, input, options);\n if (!result.success || result.data === undefined) {\n throw new AiApiClientError(\n result.error?.message ?? 'AI 任务失败',\n result.error?.code,\n result\n );\n }\n return result.data;\n}\n\nexport function createAiTaskRunner<TInput, TOutput>(\n taskId: string,\n options?: AiApiClientOptions\n) {\n return (\n input: TInput,\n runOptions?: { signal?: AbortSignal; clientSettings?: AiClientSettings }\n ) =>\n runAiTaskOrThrow<TInput, TOutput>(taskId, input, {\n ...runOptions,\n runEndpoint: options?.runEndpoint,\n fetchImpl: options?.fetchImpl,\n });\n}\n\nexport const aiApiClient = {\n run: runAiTask,\n runOrThrow: runAiTaskOrThrow,\n createRunner: createAiTaskRunner,\n};\n","import type { AiClientSettings, AiModelsListResponse } from '../types';\n\nexport async function fetchAiModels(\n clientSettings?: AiClientSettings,\n options?: { signal?: AbortSignal; modelsEndpoint?: string; fetchImpl?: typeof fetch }\n): Promise<AiModelsListResponse> {\n const fetchFn = options?.fetchImpl ?? fetch;\n const endpoint = options?.modelsEndpoint ?? '/api/ai/models';\n\n const response = await fetchFn(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ clientSettings }),\n signal: options?.signal,\n });\n\n return (await response.json()) as AiModelsListResponse;\n}\n","'use client';\n\nimport { useCallback, useState } from 'react';\nimport type { AiClientSettings, AiApiResponse } from '../../types';\nimport { runAiTask } from '../aiApiClient';\n\nexport function useAiTask<TInput, TOutput>(taskId: string) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<AiApiResponse<TOutput> | null>(null);\n\n const execute = useCallback(\n async (\n input: TInput,\n options?: { signal?: AbortSignal; clientSettings?: AiClientSettings }\n ) => {\n setLoading(true);\n setError(null);\n try {\n const response = await runAiTask<TInput, TOutput>(taskId, input, options);\n setResult(response);\n if (!response.success) {\n setError(response.error?.message ?? 'AI 任务失败');\n }\n return response;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI 任务失败';\n setError(message);\n const failed: AiApiResponse<TOutput> = {\n success: false,\n taskId,\n error: { code: 'AI_REQUEST_FAILED', message },\n };\n setResult(failed);\n return failed;\n } finally {\n setLoading(false);\n }\n },\n [taskId]\n );\n\n const reset = useCallback(() => {\n setLoading(false);\n setError(null);\n setResult(null);\n }, []);\n\n return { execute, loading, error, result, reset };\n}\n"]}
1
+ {"version":3,"sources":["../../../../src/common/aiApi/client/settingsCore.ts","../../../../src/common/aiApi/client/aiApiClient.ts","../../../../src/common/aiApi/client/fetchModels.ts","../../../../src/common/aiApi/client/hooks/useAiTask.ts","../../../../src/common/aiApi/client/hooks/useAiModels.ts","../../../../src/common/aiApi/client/hooks/useAiServerConfig.ts","../../../../src/common/aiApi/client/context/AiApiSettingsContext.tsx","../../../../src/common/aiApi/client/components/AiApiConnectivityTest.tsx","../../../../src/common/aiApi/client/components/AiApiSettingsPanel.tsx"],"names":["useState","useCallback","useEffect","React","Loader2","CheckCircle2"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { AiClientSettings, AudioStrategy } from '../types';\n\nexport interface AiApiSettings {\n apiKey: string;\n baseUrl: string;\n visionModel: string;\n textModel?: string;\n audioModel?: string;\n audioStrategy?: AudioStrategy;\n}\n\nexport const DEFAULT_AI_API_SETTINGS: AiApiSettings = {\n apiKey: '',\n baseUrl: 'https://api.openai.com/v1',\n visionModel: 'gpt-4o-mini',\n textModel: 'gpt-4o-mini',\n audioModel: 'whisper-1',\n audioStrategy: 'auto',\n};\n\nexport const AI_API_SETTINGS_STORAGE_KEY = 'ai-api-settings';\n\nexport function loadAiApiSettings(\n storageKey = AI_API_SETTINGS_STORAGE_KEY,\n defaults: AiApiSettings = DEFAULT_AI_API_SETTINGS\n): AiApiSettings {\n if (typeof window === 'undefined') return defaults;\n try {\n const raw = localStorage.getItem(storageKey);\n if (!raw) return defaults;\n return { ...defaults, ...JSON.parse(raw) };\n } catch {\n return defaults;\n }\n}\n\nexport function saveAiApiSettings(\n settings: AiApiSettings,\n storageKey = AI_API_SETTINGS_STORAGE_KEY\n): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(storageKey, JSON.stringify(settings));\n}\n\nexport function toClientSettings(settings: AiApiSettings): AiClientSettings | undefined {\n const client: AiClientSettings = {};\n if (settings.apiKey.trim()) client.apiKey = settings.apiKey.trim();\n if (settings.baseUrl.trim()) client.baseUrl = settings.baseUrl.trim();\n const visionModel = settings.visionModel.trim();\n const textModel = settings.textModel?.trim() || visionModel;\n const audioModel = settings.audioModel?.trim();\n if (visionModel) client.visionModel = visionModel;\n if (textModel) client.textModel = textModel;\n if (audioModel) client.audioModel = audioModel;\n if (settings.audioStrategy) client.audioStrategy = settings.audioStrategy;\n return Object.keys(client).length > 0 ? client : undefined;\n}\n\n/**\n * 浏览器未填写 API Key 时,完全依赖服务端环境变量(AI_API_KEY 等),\n * 避免 localStorage 中的 baseUrl/model 覆盖宿主 YAML 配置。\n */\nexport function toServerClientSettings(settings: AiApiSettings): AiClientSettings | undefined {\n if (!settings.apiKey.trim()) {\n return undefined;\n }\n return toClientSettings(settings);\n}\n\n/** 仅当浏览器填写了 API Key 时才向服务端传递 clientSettings */\nexport function pickClientSettingsFromStorage(\n storageKey = AI_API_SETTINGS_STORAGE_KEY,\n defaults: AiApiSettings = DEFAULT_AI_API_SETTINGS\n): AiClientSettings | undefined {\n return toServerClientSettings(loadAiApiSettings(storageKey, defaults));\n}\n","import type { AiApiResponse, AiApiRunRequest, AiClientSettings } from '../types';\nimport { pickClientSettingsFromStorage } from './settingsCore';\n\nexport class AiApiClientError extends Error {\n constructor(\n message: string,\n public readonly code?: string,\n public readonly response?: AiApiResponse\n ) {\n super(message);\n this.name = 'AiApiClientError';\n }\n}\n\nexport interface AiApiClientOptions {\n /** 默认 POST /api/ai/run,宿主应用可覆盖 */\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n}\n\n/**\n * 通过 HTTP 调用宿主暴露的 AI 任务入口(如 Next.js route)。\n * 连接配置可通过请求体 clientSettings 传入,或从 localStorage 读取。\n */\nexport async function runAiTask<TInput, TOutput>(\n taskId: string,\n input: TInput,\n options?: {\n signal?: AbortSignal;\n clientSettings?: AiClientSettings;\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n }\n): Promise<AiApiResponse<TOutput>> {\n const fetchFn = options?.fetchImpl ?? fetch;\n const endpoint = options?.runEndpoint ?? '/api/ai/run';\n // 显式传入 clientSettings: undefined 表示完全走服务端配置,不回退 localStorage\n const clientSettings =\n options !== undefined && 'clientSettings' in options\n ? options.clientSettings\n : pickClientSettingsFromStorage();\n\n const payload: AiApiRunRequest<TInput> = {\n taskId,\n input,\n ...(clientSettings ? { clientSettings } : {}),\n };\n\n const response = await fetchFn(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n signal: options?.signal,\n });\n\n const data = (await response.json()) as AiApiResponse<TOutput>;\n return data;\n}\n\nexport async function runAiTaskOrThrow<TInput, TOutput>(\n taskId: string,\n input: TInput,\n options?: {\n signal?: AbortSignal;\n clientSettings?: AiClientSettings;\n runEndpoint?: string;\n fetchImpl?: typeof fetch;\n }\n): Promise<TOutput> {\n const result = await runAiTask<TInput, TOutput>(taskId, input, options);\n if (!result.success || result.data === undefined) {\n throw new AiApiClientError(\n result.error?.message ?? 'AI 任务失败',\n result.error?.code,\n result\n );\n }\n return result.data;\n}\n\nexport function createAiTaskRunner<TInput, TOutput>(\n taskId: string,\n options?: AiApiClientOptions\n) {\n return (\n input: TInput,\n runOptions?: { signal?: AbortSignal; clientSettings?: AiClientSettings }\n ) =>\n runAiTaskOrThrow<TInput, TOutput>(taskId, input, {\n ...runOptions,\n runEndpoint: options?.runEndpoint,\n fetchImpl: options?.fetchImpl,\n });\n}\n\nexport const aiApiClient = {\n run: runAiTask,\n runOrThrow: runAiTaskOrThrow,\n createRunner: createAiTaskRunner,\n};\n","import type { AiClientSettings, AiModelsListResponse } from '../types';\n\nexport async function fetchAiModels(\n clientSettings?: AiClientSettings,\n options?: { signal?: AbortSignal; modelsEndpoint?: string; fetchImpl?: typeof fetch }\n): Promise<AiModelsListResponse> {\n const fetchFn = options?.fetchImpl ?? fetch;\n const endpoint = options?.modelsEndpoint ?? '/api/ai/models';\n\n const body: { clientSettings?: AiClientSettings } = {};\n if (clientSettings) {\n body.clientSettings = clientSettings;\n }\n\n const response = await fetchFn(endpoint, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n signal: options?.signal,\n });\n\n return (await response.json()) as AiModelsListResponse;\n}\n","'use client';\n\nimport { useCallback, useState } from 'react';\nimport type { AiClientSettings, AiApiResponse } from '../../types';\nimport { runAiTask } from '../aiApiClient';\n\nexport function useAiTask<TInput, TOutput>(taskId: string) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [result, setResult] = useState<AiApiResponse<TOutput> | null>(null);\n\n const execute = useCallback(\n async (\n input: TInput,\n options?: { signal?: AbortSignal; clientSettings?: AiClientSettings }\n ) => {\n setLoading(true);\n setError(null);\n try {\n const response = await runAiTask<TInput, TOutput>(taskId, input, options);\n setResult(response);\n if (!response.success) {\n setError(response.error?.message ?? 'AI 任务失败');\n }\n return response;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'AI 任务失败';\n setError(message);\n const failed: AiApiResponse<TOutput> = {\n success: false,\n taskId,\n error: { code: 'AI_REQUEST_FAILED', message },\n };\n setResult(failed);\n return failed;\n } finally {\n setLoading(false);\n }\n },\n [taskId]\n );\n\n const reset = useCallback(() => {\n setLoading(false);\n setError(null);\n setResult(null);\n }, []);\n\n return { execute, loading, error, result, reset };\n}\n","'use client';\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { fetchAiModels } from '../fetchModels';\nimport type { AiApiSettings } from '../settingsCore';\nimport { toServerClientSettings } from '../settingsCore';\n\nexport interface UseAiModelsOptions {\n modelsEndpoint?: string;\n debounceMs?: number;\n}\n\nexport interface UseAiModelsResult {\n visionModels: string[];\n allModels: string[];\n loading: boolean;\n error: string | null;\n refresh: () => void;\n}\n\nexport function useAiModels(\n settings: AiApiSettings,\n onSuggestedModel?: (model: string) => void,\n options?: UseAiModelsOptions\n): UseAiModelsResult {\n const [visionModels, setVisionModels] = useState<string[]>([]);\n const [allModels, setAllModels] = useState<string[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const onSuggestedRef = useRef(onSuggestedModel);\n const settingsRef = useRef(settings);\n onSuggestedRef.current = onSuggestedModel;\n settingsRef.current = settings;\n\n const load = useCallback(async () => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setLoading(true);\n setError(null);\n\n const currentSettings = settingsRef.current;\n\n try {\n const clientSettings = toServerClientSettings(currentSettings);\n const result = await fetchAiModels(clientSettings, {\n signal: controller.signal,\n modelsEndpoint: options?.modelsEndpoint,\n });\n\n if (controller.signal.aborted) return;\n\n if (!result.success) {\n setVisionModels([]);\n setAllModels([]);\n setError(result.error?.message ?? '获取模型列表失败');\n return;\n }\n\n setVisionModels(result.visionModels);\n setAllModels(result.models);\n\n if (result.suggestedVisionModel) {\n const current = currentSettings.visionModel.trim();\n const shouldAutoSelect =\n !current ||\n (!result.visionModels.includes(current) && !result.models.includes(current));\n\n if (shouldAutoSelect) {\n onSuggestedRef.current?.(result.suggestedVisionModel);\n }\n }\n } catch (err) {\n if (controller.signal.aborted) return;\n setVisionModels([]);\n setAllModels([]);\n setError(err instanceof Error ? err.message : '获取模型列表失败');\n } finally {\n if (!controller.signal.aborted) {\n setLoading(false);\n }\n }\n }, [options?.modelsEndpoint, settings.apiKey, settings.baseUrl]);\n\n useEffect(() => {\n const debounceMs = options?.debounceMs ?? 600;\n const timer = window.setTimeout(() => {\n void load();\n }, debounceMs);\n\n return () => {\n window.clearTimeout(timer);\n abortRef.current?.abort();\n };\n }, [load, options?.debounceMs]);\n\n return {\n visionModels,\n allModels,\n loading,\n error,\n refresh: load,\n };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { AiServerConfigStatus } from '../../types';\n\nexport interface UseAiServerConfigOptions {\n /** 宿主实现的配置状态端点,默认 GET /api/ai/config */\n configEndpoint?: string;\n}\n\nexport function useAiServerConfig(options?: UseAiServerConfigOptions) {\n const [config, setConfig] = useState<AiServerConfigStatus | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const configEndpoint = options?.configEndpoint ?? '/api/ai/config';\n\n useEffect(() => {\n let cancelled = false;\n\n async function load() {\n try {\n const response = await fetch(configEndpoint, { credentials: 'include' });\n if (!response.ok) {\n if (!cancelled) {\n setConfig({ serverConfigured: false });\n setError(response.status === 401 ? '请先登录' : '无法读取服务端配置');\n }\n return;\n }\n const data = (await response.json()) as AiServerConfigStatus;\n if (!cancelled) {\n setConfig(data);\n setError(null);\n }\n } catch (err) {\n if (!cancelled) {\n setConfig({ serverConfigured: false });\n setError(err instanceof Error ? err.message : '无法读取服务端配置');\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n\n void load();\n return () => {\n cancelled = true;\n };\n }, [configEndpoint]);\n\n return { config, loading, error };\n}\n","'use client';\n\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n type AiApiSettings,\n DEFAULT_AI_API_SETTINGS,\n loadAiApiSettings,\n saveAiApiSettings,\n} from '../settingsCore';\n\nexport interface AiApiSettingsContextValue {\n settings: AiApiSettings;\n updateSettings: (updates: Partial<AiApiSettings>) => void;\n resetSettings: () => void;\n}\n\nexport interface AiApiSettingsProviderProps {\n children: React.ReactNode;\n /** 宿主可覆盖默认 baseUrl / model(如 MiMo) */\n defaultSettings?: Partial<AiApiSettings>;\n storageKey?: string;\n}\n\nconst AiApiSettingsContext = createContext<AiApiSettingsContextValue | null>(null);\n\nexport function AiApiSettingsProvider({\n children,\n defaultSettings,\n storageKey,\n}: AiApiSettingsProviderProps) {\n const mergedDefaults = useMemo(\n () => ({ ...DEFAULT_AI_API_SETTINGS, ...defaultSettings }),\n [defaultSettings]\n );\n\n const [settings, setSettings] = useState<AiApiSettings>(mergedDefaults);\n\n useEffect(() => {\n setSettings(loadAiApiSettings(storageKey, mergedDefaults));\n }, [storageKey, mergedDefaults]);\n\n const persist = useCallback(\n (next: AiApiSettings) => {\n setSettings(next);\n saveAiApiSettings(next, storageKey);\n },\n [storageKey]\n );\n\n const updateSettings = useCallback(\n (updates: Partial<AiApiSettings>) => {\n setSettings((prev) => {\n const next = { ...prev, ...updates };\n saveAiApiSettings(next, storageKey);\n return next;\n });\n },\n [storageKey]\n );\n\n const resetSettings = useCallback(() => {\n persist(mergedDefaults);\n }, [persist, mergedDefaults]);\n\n const value = useMemo(\n () => ({ settings, updateSettings, resetSettings }),\n [settings, updateSettings, resetSettings]\n );\n\n return (\n <AiApiSettingsContext.Provider value={value}>{children}</AiApiSettingsContext.Provider>\n );\n}\n\nexport function useAiApiSettings() {\n const ctx = useContext(AiApiSettingsContext);\n if (!ctx) {\n throw new Error('useAiApiSettings must be used within AiApiSettingsProvider');\n }\n return ctx;\n}\n","'use client';\n\nimport React, { useCallback, useState } from 'react';\nimport { CheckCircle2, Loader2, Wifi, XCircle } from 'lucide-react';\nimport { CORE_CONNECTIVITY_TEST_TASK_ID } from '../../types';\nimport type { ConnectivityTestOutput } from '../../types';\nimport { useAiApiSettings } from '../context/AiApiSettingsContext';\nimport { runAiTask } from '../aiApiClient';\nimport { toServerClientSettings } from '../settingsCore';\n\ntype TestStatus = 'idle' | 'loading' | 'success' | 'error';\n\nexport interface AiApiConnectivityTestProps {\n runEndpoint?: string;\n}\n\nexport function AiApiConnectivityTest({ runEndpoint }: AiApiConnectivityTestProps) {\n const { settings } = useAiApiSettings();\n const [status, setStatus] = useState<TestStatus>('idle');\n const [message, setMessage] = useState('');\n const [meta, setMeta] = useState<{ model?: string; latencyMs?: number } | null>(null);\n\n const handleTest = useCallback(async () => {\n setStatus('loading');\n setMessage('');\n setMeta(null);\n\n const started = Date.now();\n const clientSettings = toServerClientSettings(settings);\n\n try {\n const result = await runAiTask<Record<string, never>, ConnectivityTestOutput>(\n CORE_CONNECTIVITY_TEST_TASK_ID,\n {},\n { clientSettings, runEndpoint }\n );\n\n const latencyMs = result.meta?.latencyMs ?? Date.now() - started;\n\n if (!result.success) {\n setStatus('error');\n setMessage(result.error?.message ?? '连通性测试失败');\n setMeta({ latencyMs });\n return;\n }\n\n setStatus('success');\n setMessage(result.data?.reply ? `响应:${result.data.reply}` : '连接正常');\n setMeta({ model: result.meta?.model, latencyMs });\n } catch (err) {\n setStatus('error');\n setMessage(err instanceof Error ? err.message : '网络请求失败');\n setMeta({ latencyMs: Date.now() - started });\n }\n }, [settings, runEndpoint]);\n\n return (\n <div className=\"rounded-xl border border-slate-200 bg-slate-50/80 p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h3 className=\"text-sm font-medium text-slate-900\">连通性测试</h3>\n <p className=\"mt-1 text-xs text-slate-500\">\n 使用当前填写的 Key、Base URL 与模型发起一次轻量请求(需已登录)。未填写 Key 时将使用服务端配置。\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => void handleTest()}\n disabled={status === 'loading'}\n className=\"inline-flex h-10 items-center gap-2 rounded-lg bg-slate-900 px-4 text-sm font-medium text-white transition-transform hover:bg-slate-800 active:scale-[0.98] disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {status === 'loading' ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Wifi className=\"h-4 w-4\" />\n )}\n {status === 'loading' ? '测试中…' : '测试连接'}\n </button>\n </div>\n\n {status !== 'idle' && (\n <div\n className={`mt-3 flex items-start gap-2 rounded-lg px-3 py-2.5 text-sm ${\n status === 'success'\n ? 'bg-emerald-50 text-emerald-800'\n : status === 'error'\n ? 'bg-red-50 text-red-800'\n : 'bg-white text-slate-600'\n }`}\n >\n {status === 'loading' && <Loader2 className=\"mt-0.5 h-4 w-4 shrink-0 animate-spin\" />}\n {status === 'success' && <CheckCircle2 className=\"mt-0.5 h-4 w-4 shrink-0\" />}\n {status === 'error' && <XCircle className=\"mt-0.5 h-4 w-4 shrink-0\" />}\n <div className=\"min-w-0\">\n <p className=\"text-pretty\">{status === 'loading' ? '正在连接 AI 服务…' : message}</p>\n {meta && (meta.model || meta.latencyMs !== undefined) && status !== 'loading' && (\n <p className=\"mt-1 tabular-nums text-xs opacity-80\">\n {meta.model && <span>模型 {meta.model}</span>}\n {meta.model && meta.latencyMs !== undefined && <span> · </span>}\n {meta.latencyMs !== undefined && <span>{meta.latencyMs} ms</span>}\n </p>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport React, { useCallback, useState } from 'react';\nimport { CheckCircle2, Loader2, RefreshCw, Server } from 'lucide-react';\nimport { useAiApiSettings } from '../context/AiApiSettingsContext';\nimport { useAiModels } from '../hooks/useAiModels';\nimport { useAiServerConfig } from '../hooks/useAiServerConfig';\nimport { AiApiConnectivityTest } from './AiApiConnectivityTest';\n\nexport interface AiApiSettingsPanelProps {\n /** 宿主实现的配置状态端点 */\n serverConfigEndpoint?: string;\n modelsEndpoint?: string;\n runEndpoint?: string;\n /** 未配置服务端时的提示文案 */\n serverMissingHint?: React.ReactNode;\n apiKeyPlaceholder?: string;\n baseUrlPlaceholder?: string;\n visionModelPlaceholder?: string;\n}\n\nexport function AiApiSettingsPanel({\n serverConfigEndpoint,\n modelsEndpoint,\n runEndpoint,\n serverMissingHint,\n apiKeyPlaceholder = 'sk-…',\n baseUrlPlaceholder = 'https://api.openai.com/v1',\n visionModelPlaceholder = 'gpt-4o-mini',\n}: AiApiSettingsPanelProps) {\n const { settings, updateSettings } = useAiApiSettings();\n const { config: serverConfig, loading: serverLoading } = useAiServerConfig({\n configEndpoint: serverConfigEndpoint,\n });\n const [showOverride, setShowOverride] = useState(false);\n\n const hasBrowserKey = Boolean(settings.apiKey.trim());\n const serverReady = Boolean(serverConfig?.serverConfigured);\n const useServerOnly = serverReady && !hasBrowserKey && !showOverride;\n\n const handleSuggestedModel = useCallback(\n (model: string) => {\n updateSettings({ visionModel: model });\n },\n [updateSettings]\n );\n\n const { visionModels, allModels, loading, error, refresh } = useAiModels(\n settings,\n handleSuggestedModel,\n { modelsEndpoint }\n );\n\n const selectableModels = visionModels;\n const showDropdown = selectableModels.length > 0;\n const showAllModelsFallback = visionModels.length === 0 && allModels.length > 0;\n\n const defaultServerMissingHint = (\n <>\n 请在宿主配置文件中填写 AI API Key(如 YAML 的 <code className=\"rounded bg-amber-100 px-1\">ai.apiKey</code>\n ),或在下方的浏览器设置中填写。\n </>\n );\n\n return (\n <div className=\"space-y-6\">\n {serverLoading ? (\n <div className=\"flex items-center gap-2 rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 text-sm text-slate-600\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n 正在检查服务端 AI 配置…\n </div>\n ) : serverReady && !hasBrowserKey ? (\n <div className=\"rounded-xl border border-emerald-200 bg-emerald-50/80 p-4\">\n <div className=\"flex items-start gap-3\">\n <CheckCircle2 className=\"mt-0.5 h-5 w-5 shrink-0 text-emerald-600\" />\n <div className=\"min-w-0\">\n <h3 className=\"text-sm font-medium text-emerald-900\">已由服务端配置</h3>\n <p className=\"mt-1 text-xs text-emerald-800/90\">\n AI 功能将使用服务端配置的 API Key,无需在此重复填写。\n </p>\n <dl className=\"mt-3 grid gap-1 text-xs text-emerald-900/80\">\n {serverConfig?.baseUrl && (\n <div className=\"flex gap-2\">\n <dt className=\"shrink-0 font-medium\">Base URL</dt>\n <dd className=\"truncate font-mono\">{serverConfig.baseUrl}</dd>\n </div>\n )}\n {serverConfig?.visionModel && (\n <div className=\"flex gap-2\">\n <dt className=\"shrink-0 font-medium\">视觉模型</dt>\n <dd className=\"font-mono\">{serverConfig.visionModel}</dd>\n </div>\n )}\n </dl>\n <button\n type=\"button\"\n onClick={() => setShowOverride((v) => !v)}\n className=\"mt-3 text-xs font-medium text-emerald-700 underline-offset-2 hover:underline\"\n >\n {showOverride ? '收起自定义配置' : '高级:使用浏览器自定义 Key 覆盖服务端'}\n </button>\n </div>\n </div>\n </div>\n ) : !serverReady && !hasBrowserKey ? (\n <div className=\"rounded-xl border border-amber-200 bg-amber-50/80 p-4\">\n <div className=\"flex items-start gap-3\">\n <Server className=\"mt-0.5 h-5 w-5 shrink-0 text-amber-600\" />\n <div>\n <h3 className=\"text-sm font-medium text-amber-900\">服务端未配置 AI</h3>\n <p className=\"mt-1 text-xs text-amber-800/90\">\n {serverMissingHint ?? defaultServerMissingHint}\n </p>\n </div>\n </div>\n </div>\n ) : null}\n\n {!useServerOnly && (\n <>\n <div>\n <label htmlFor=\"ai-api-key\" className=\"mb-2 block text-sm font-medium text-gray-700\">\n API Key\n </label>\n <input\n id=\"ai-api-key\"\n type=\"password\"\n autoComplete=\"off\"\n value={settings.apiKey}\n onChange={(e) => updateSettings({ apiKey: e.target.value })}\n placeholder={apiKeyPlaceholder}\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 font-mono text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <p className=\"mt-1.5 text-xs text-gray-500\">\n 保存在本机浏览器。填写后将覆盖服务端配置;留空则使用服务端密钥。\n </p>\n </div>\n\n <div>\n <label htmlFor=\"ai-base-url\" className=\"mb-2 block text-sm font-medium text-gray-700\">\n API Base URL\n </label>\n <input\n id=\"ai-base-url\"\n type=\"url\"\n value={settings.baseUrl}\n onChange={(e) => updateSettings({ baseUrl: e.target.value })}\n placeholder={baseUrlPlaceholder}\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <p className=\"mt-1.5 text-xs text-gray-500\">\n 填写 Key 与地址后将自动拉取可用模型并选择合适的视觉模型。\n </p>\n </div>\n </>\n )}\n\n {!useServerOnly && (\n <>\n <div>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <label htmlFor=\"ai-vision-model\" className=\"text-sm font-medium text-gray-700\">\n 视觉模型\n </label>\n <button\n type=\"button\"\n onClick={() => void refresh()}\n disabled={loading}\n className=\"inline-flex items-center gap-1 rounded-md px-2 py-1 text-xs text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700 disabled:opacity-50\"\n >\n {loading ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <RefreshCw className=\"h-3.5 w-3.5\" />\n )}\n 刷新模型\n </button>\n </div>\n\n {showDropdown ? (\n <select\n id=\"ai-vision-model\"\n value={settings.visionModel}\n onChange={(e) => updateSettings({ visionModel: e.target.value })}\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n >\n {selectableModels.map((model) => (\n <option key={model} value={model}>\n {model}\n </option>\n ))}\n {settings.visionModel && !selectableModels.includes(settings.visionModel) && (\n <option value={settings.visionModel}>{settings.visionModel}(当前)</option>\n )}\n </select>\n ) : (\n <input\n id=\"ai-vision-model\"\n type=\"text\"\n value={settings.visionModel}\n onChange={(e) => updateSettings({ visionModel: e.target.value })}\n placeholder={visionModelPlaceholder}\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n )}\n\n {loading && (\n <p className=\"mt-1.5 flex items-center gap-1.5 text-xs text-gray-500\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n 正在读取可用模型…\n </p>\n )}\n {!loading && error && (\n <p className=\"mt-1.5 text-xs text-amber-600\">\n 无法自动获取模型列表:{error}。可手动填写模型名称。\n </p>\n )}\n {!loading && !error && showDropdown && (\n <p className=\"mt-1.5 text-xs text-gray-500\">\n 已加载 {selectableModels.length} 个\n {visionModels.length > 0 ? '视觉' : '对话'}模型,可手动切换。\n </p>\n )}\n {!loading && !error && showAllModelsFallback && (\n <p className=\"mt-1.5 text-xs text-amber-600\">\n 未识别到视觉模型,请手动填写支持识图的模型名。\n </p>\n )}\n {!loading && !error && !showDropdown && !showAllModelsFallback && (\n <p className=\"mt-1.5 text-xs text-gray-500\">需支持图片输入的多模态模型。</p>\n )}\n </div>\n\n <div>\n <label htmlFor=\"ai-text-model\" className=\"mb-2 block text-sm font-medium text-gray-700\">\n 文本模型\n </label>\n <input\n id=\"ai-text-model\"\n type=\"text\"\n value={settings.textModel ?? settings.visionModel}\n onChange={(e) => updateSettings({ textModel: e.target.value })}\n placeholder={visionModelPlaceholder}\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <p className=\"mt-1.5 text-xs text-gray-500\">纯文本与 STT 转写后的对话;默认同视觉模型。</p>\n </div>\n\n <div>\n <label htmlFor=\"ai-audio-model\" className=\"mb-2 block text-sm font-medium text-gray-700\">\n 语音转写模型(STT)\n </label>\n <input\n id=\"ai-audio-model\"\n type=\"text\"\n value={settings.audioModel ?? 'whisper-1'}\n onChange={(e) => updateSettings({ audioModel: e.target.value })}\n placeholder=\"whisper-1\"\n className=\"w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500\"\n />\n <p className=\"mt-1.5 text-xs text-gray-500\">\n 多模态 auto 模式下,不支持内嵌音频时将用此模型转写(Whisper 等)。\n </p>\n </div>\n </>\n )}\n\n <AiApiConnectivityTest runEndpoint={runEndpoint} />\n </div>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { A as AiClientSettings, d as AiConnectionConfig, M as MultimodalChatParams, e as MultimodalChatResult, f as AiImageInput, g as AiAudioInput, h as AiMediaInput, c as AudioStrategy, i as AiTaskDefinition, j as AiTaskContext, a as AiApiResponse, T as TextCompletionInput, k as TextCompletionOutput, S as StructuredMultimodalInput, l as StructuredMultimodalOutput, C as ConnectivityTestOutput } from '../../types-CiqMQ-uu.mjs';
2
- export { p as AiApiErrorBody, q as AiApiErrorCode, r as AiApiResponseMeta, n as AiApiRunRequest, u as AiAudioMediaInput, m as AiConnectionSettings, t as AiImageMediaInput, s as AiMediaKind, y as AiModelsListRequest, b as AiModelsListResponse, o as AiTaskRunOptions, x as CORE_CONNECTIVITY_TEST_TASK_ID, v as CORE_LLM_COMPLETION_TASK_ID, w as CORE_STRUCTURED_MULTIMODAL_TASK_ID } from '../../types-CiqMQ-uu.mjs';
1
+ import { A as AiClientSettings, e as AiConnectionConfig, M as MultimodalChatParams, f as MultimodalChatResult, g as AiImageInput, h as AiAudioInput, i as AiMediaInput, c as AudioStrategy, j as AiTaskDefinition, k as AiTaskContext, a as AiApiResponse, T as TextCompletionInput, l as TextCompletionOutput, S as StructuredMultimodalInput, m as StructuredMultimodalOutput, C as ConnectivityTestOutput } from '../../types-DgbG0Of-.mjs';
2
+ export { q as AiApiErrorBody, r as AiApiErrorCode, s as AiApiResponseMeta, o as AiApiRunRequest, v as AiAudioMediaInput, n as AiConnectionSettings, u as AiImageMediaInput, t as AiMediaKind, z as AiModelsListRequest, b as AiModelsListResponse, d as AiServerConfigStatus, p as AiTaskRunOptions, y as CORE_CONNECTIVITY_TEST_TASK_ID, w as CORE_LLM_COMPLETION_TASK_ID, x as CORE_STRUCTURED_MULTIMODAL_TASK_ID } from '../../types-DgbG0Of-.mjs';
3
3
  import { R as RequestAdapter } from '../../types-CbTsi9CZ.mjs';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { A as AiClientSettings, d as AiConnectionConfig, M as MultimodalChatParams, e as MultimodalChatResult, f as AiImageInput, g as AiAudioInput, h as AiMediaInput, c as AudioStrategy, i as AiTaskDefinition, j as AiTaskContext, a as AiApiResponse, T as TextCompletionInput, k as TextCompletionOutput, S as StructuredMultimodalInput, l as StructuredMultimodalOutput, C as ConnectivityTestOutput } from '../../types-CiqMQ-uu.js';
2
- export { p as AiApiErrorBody, q as AiApiErrorCode, r as AiApiResponseMeta, n as AiApiRunRequest, u as AiAudioMediaInput, m as AiConnectionSettings, t as AiImageMediaInput, s as AiMediaKind, y as AiModelsListRequest, b as AiModelsListResponse, o as AiTaskRunOptions, x as CORE_CONNECTIVITY_TEST_TASK_ID, v as CORE_LLM_COMPLETION_TASK_ID, w as CORE_STRUCTURED_MULTIMODAL_TASK_ID } from '../../types-CiqMQ-uu.js';
1
+ import { A as AiClientSettings, e as AiConnectionConfig, M as MultimodalChatParams, f as MultimodalChatResult, g as AiImageInput, h as AiAudioInput, i as AiMediaInput, c as AudioStrategy, j as AiTaskDefinition, k as AiTaskContext, a as AiApiResponse, T as TextCompletionInput, l as TextCompletionOutput, S as StructuredMultimodalInput, m as StructuredMultimodalOutput, C as ConnectivityTestOutput } from '../../types-DgbG0Of-.js';
2
+ export { q as AiApiErrorBody, r as AiApiErrorCode, s as AiApiResponseMeta, o as AiApiRunRequest, v as AiAudioMediaInput, n as AiConnectionSettings, u as AiImageMediaInput, t as AiMediaKind, z as AiModelsListRequest, b as AiModelsListResponse, d as AiServerConfigStatus, p as AiTaskRunOptions, y as CORE_CONNECTIVITY_TEST_TASK_ID, w as CORE_LLM_COMPLETION_TASK_ID, x as CORE_STRUCTURED_MULTIMODAL_TASK_ID } from '../../types-DgbG0Of-.js';
3
3
  import { R as RequestAdapter } from '../../types-CbTsi9CZ.js';
4
4
 
5
5
  /**
@@ -1,217 +1,218 @@
1
1
  'use strict';
2
2
 
3
- var chunkXPY45Y75_js = require('../../chunk-XPY45Y75.js');
3
+ var chunkVVHFMAE7_js = require('../../chunk-VVHFMAE7.js');
4
+ var chunkGJVEYCS4_js = require('../../chunk-GJVEYCS4.js');
4
5
  require('../../chunk-NSBPE2FW.js');
5
6
 
6
7
 
7
8
 
8
- Object.defineProperty(exports, "CORE_CONNECTIVITY_TEST_TASK_ID", {
9
- enumerable: true,
10
- get: function () { return chunkXPY45Y75_js.CORE_CONNECTIVITY_TEST_TASK_ID; }
11
- });
12
- Object.defineProperty(exports, "CORE_LLM_COMPLETION_TASK_ID", {
13
- enumerable: true,
14
- get: function () { return chunkXPY45Y75_js.CORE_LLM_COMPLETION_TASK_ID; }
15
- });
16
- Object.defineProperty(exports, "CORE_STRUCTURED_MULTIMODAL_TASK_ID", {
17
- enumerable: true,
18
- get: function () { return chunkXPY45Y75_js.CORE_STRUCTURED_MULTIMODAL_TASK_ID; }
19
- });
20
9
  Object.defineProperty(exports, "DEFAULT_OPENAI_BASE_URL", {
21
10
  enumerable: true,
22
- get: function () { return chunkXPY45Y75_js.DEFAULT_OPENAI_BASE_URL; }
11
+ get: function () { return chunkVVHFMAE7_js.DEFAULT_OPENAI_BASE_URL; }
23
12
  });
24
13
  Object.defineProperty(exports, "DEFAULT_TEXT_MODEL", {
25
14
  enumerable: true,
26
- get: function () { return chunkXPY45Y75_js.DEFAULT_TEXT_MODEL; }
15
+ get: function () { return chunkVVHFMAE7_js.DEFAULT_TEXT_MODEL; }
27
16
  });
28
17
  Object.defineProperty(exports, "appendTranscriptionsToPrompt", {
29
18
  enumerable: true,
30
- get: function () { return chunkXPY45Y75_js.appendTranscriptionsToPrompt; }
19
+ get: function () { return chunkVVHFMAE7_js.appendTranscriptionsToPrompt; }
31
20
  });
32
21
  Object.defineProperty(exports, "assertMultimodalCapableModel", {
33
22
  enumerable: true,
34
- get: function () { return chunkXPY45Y75_js.assertMultimodalCapableModel; }
23
+ get: function () { return chunkVVHFMAE7_js.assertMultimodalCapableModel; }
35
24
  });
36
25
  Object.defineProperty(exports, "assertValidAudioInput", {
37
26
  enumerable: true,
38
- get: function () { return chunkXPY45Y75_js.assertValidAudioInput; }
27
+ get: function () { return chunkVVHFMAE7_js.assertValidAudioInput; }
39
28
  });
40
29
  Object.defineProperty(exports, "assertValidImageInput", {
41
30
  enumerable: true,
42
- get: function () { return chunkXPY45Y75_js.assertValidImageInput; }
31
+ get: function () { return chunkVVHFMAE7_js.assertValidImageInput; }
43
32
  });
44
33
  Object.defineProperty(exports, "assertValidMultimodalMedia", {
45
34
  enumerable: true,
46
- get: function () { return chunkXPY45Y75_js.assertValidMultimodalMedia; }
35
+ get: function () { return chunkVVHFMAE7_js.assertValidMultimodalMedia; }
47
36
  });
48
37
  Object.defineProperty(exports, "assertVisionCapableModel", {
49
38
  enumerable: true,
50
- get: function () { return chunkXPY45Y75_js.assertVisionCapableModel; }
39
+ get: function () { return chunkVVHFMAE7_js.assertVisionCapableModel; }
51
40
  });
52
41
  Object.defineProperty(exports, "base64ToBlob", {
53
42
  enumerable: true,
54
- get: function () { return chunkXPY45Y75_js.base64ToBlob; }
43
+ get: function () { return chunkVVHFMAE7_js.base64ToBlob; }
55
44
  });
56
45
  Object.defineProperty(exports, "buildMultimodalMessages", {
57
46
  enumerable: true,
58
- get: function () { return chunkXPY45Y75_js.buildMultimodalMessages; }
47
+ get: function () { return chunkVVHFMAE7_js.buildMultimodalMessages; }
59
48
  });
60
49
  Object.defineProperty(exports, "callChat", {
61
50
  enumerable: true,
62
- get: function () { return chunkXPY45Y75_js.callChat; }
51
+ get: function () { return chunkVVHFMAE7_js.callChat; }
63
52
  });
64
53
  Object.defineProperty(exports, "callCompletion", {
65
54
  enumerable: true,
66
- get: function () { return chunkXPY45Y75_js.callCompletion; }
55
+ get: function () { return chunkVVHFMAE7_js.callCompletion; }
67
56
  });
68
57
  Object.defineProperty(exports, "callMultimodalChat", {
69
58
  enumerable: true,
70
- get: function () { return chunkXPY45Y75_js.callMultimodalChat; }
59
+ get: function () { return chunkVVHFMAE7_js.callMultimodalChat; }
71
60
  });
72
61
  Object.defineProperty(exports, "clearAiTasksForTest", {
73
62
  enumerable: true,
74
- get: function () { return chunkXPY45Y75_js.clearAiTasksForTest; }
63
+ get: function () { return chunkVVHFMAE7_js.clearAiTasksForTest; }
75
64
  });
76
65
  Object.defineProperty(exports, "coreConnectivityTestTask", {
77
66
  enumerable: true,
78
- get: function () { return chunkXPY45Y75_js.coreConnectivityTestTask; }
67
+ get: function () { return chunkVVHFMAE7_js.coreConnectivityTestTask; }
79
68
  });
80
69
  Object.defineProperty(exports, "coreLlmCompletionTask", {
81
70
  enumerable: true,
82
- get: function () { return chunkXPY45Y75_js.coreLlmCompletionTask; }
71
+ get: function () { return chunkVVHFMAE7_js.coreLlmCompletionTask; }
83
72
  });
84
73
  Object.defineProperty(exports, "coreStructuredMultimodalTask", {
85
74
  enumerable: true,
86
- get: function () { return chunkXPY45Y75_js.coreStructuredMultimodalTask; }
75
+ get: function () { return chunkVVHFMAE7_js.coreStructuredMultimodalTask; }
87
76
  });
88
77
  Object.defineProperty(exports, "detectVisionMessageFormat", {
89
78
  enumerable: true,
90
- get: function () { return chunkXPY45Y75_js.detectVisionMessageFormat; }
79
+ get: function () { return chunkVVHFMAE7_js.detectVisionMessageFormat; }
91
80
  });
92
81
  Object.defineProperty(exports, "ensureCoreAiTasksRegistered", {
93
82
  enumerable: true,
94
- get: function () { return chunkXPY45Y75_js.ensureCoreAiTasksRegistered; }
83
+ get: function () { return chunkVVHFMAE7_js.ensureCoreAiTasksRegistered; }
95
84
  });
96
85
  Object.defineProperty(exports, "extractJsonObject", {
97
86
  enumerable: true,
98
- get: function () { return chunkXPY45Y75_js.extractJsonObject; }
87
+ get: function () { return chunkVVHFMAE7_js.extractJsonObject; }
99
88
  });
100
89
  Object.defineProperty(exports, "fileToAiAudioInput", {
101
90
  enumerable: true,
102
- get: function () { return chunkXPY45Y75_js.fileToAiAudioInput; }
91
+ get: function () { return chunkVVHFMAE7_js.fileToAiAudioInput; }
103
92
  });
104
93
  Object.defineProperty(exports, "fileToAiImageInput", {
105
94
  enumerable: true,
106
- get: function () { return chunkXPY45Y75_js.fileToAiImageInput; }
95
+ get: function () { return chunkVVHFMAE7_js.fileToAiImageInput; }
107
96
  });
108
97
  Object.defineProperty(exports, "filterChatModels", {
109
98
  enumerable: true,
110
- get: function () { return chunkXPY45Y75_js.filterChatModels; }
99
+ get: function () { return chunkVVHFMAE7_js.filterChatModels; }
111
100
  });
112
101
  Object.defineProperty(exports, "filterSttModels", {
113
102
  enumerable: true,
114
- get: function () { return chunkXPY45Y75_js.filterSttModels; }
103
+ get: function () { return chunkVVHFMAE7_js.filterSttModels; }
115
104
  });
116
105
  Object.defineProperty(exports, "filterVisionModels", {
117
106
  enumerable: true,
118
- get: function () { return chunkXPY45Y75_js.filterVisionModels; }
107
+ get: function () { return chunkVVHFMAE7_js.filterVisionModels; }
119
108
  });
120
109
  Object.defineProperty(exports, "getAiTask", {
121
110
  enumerable: true,
122
- get: function () { return chunkXPY45Y75_js.getAiTask; }
111
+ get: function () { return chunkVVHFMAE7_js.getAiTask; }
123
112
  });
124
113
  Object.defineProperty(exports, "isAudioInputError", {
125
114
  enumerable: true,
126
- get: function () { return chunkXPY45Y75_js.isAudioInputError; }
115
+ get: function () { return chunkVVHFMAE7_js.isAudioInputError; }
127
116
  });
128
117
  Object.defineProperty(exports, "isImageUrlVariantError", {
129
118
  enumerable: true,
130
- get: function () { return chunkXPY45Y75_js.isImageUrlVariantError; }
119
+ get: function () { return chunkVVHFMAE7_js.isImageUrlVariantError; }
131
120
  });
132
121
  Object.defineProperty(exports, "isKnownTextOnlyModel", {
133
122
  enumerable: true,
134
- get: function () { return chunkXPY45Y75_js.isKnownTextOnlyModel; }
123
+ get: function () { return chunkVVHFMAE7_js.isKnownTextOnlyModel; }
135
124
  });
136
125
  Object.defineProperty(exports, "isLikelyNativeAudioChatModel", {
137
126
  enumerable: true,
138
- get: function () { return chunkXPY45Y75_js.isLikelyNativeAudioChatModel; }
127
+ get: function () { return chunkVVHFMAE7_js.isLikelyNativeAudioChatModel; }
139
128
  });
140
129
  Object.defineProperty(exports, "isLikelySttModel", {
141
130
  enumerable: true,
142
- get: function () { return chunkXPY45Y75_js.isLikelySttModel; }
131
+ get: function () { return chunkVVHFMAE7_js.isLikelySttModel; }
143
132
  });
144
133
  Object.defineProperty(exports, "isLikelyVisionModel", {
145
134
  enumerable: true,
146
- get: function () { return chunkXPY45Y75_js.isLikelyVisionModel; }
135
+ get: function () { return chunkVVHFMAE7_js.isLikelyVisionModel; }
147
136
  });
148
137
  Object.defineProperty(exports, "listAiTasks", {
149
138
  enumerable: true,
150
- get: function () { return chunkXPY45Y75_js.listAiTasks; }
139
+ get: function () { return chunkVVHFMAE7_js.listAiTasks; }
151
140
  });
152
141
  Object.defineProperty(exports, "listOpenAiCompatibleModels", {
153
142
  enumerable: true,
154
- get: function () { return chunkXPY45Y75_js.listOpenAiCompatibleModels; }
143
+ get: function () { return chunkVVHFMAE7_js.listOpenAiCompatibleModels; }
155
144
  });
156
145
  Object.defineProperty(exports, "mimeToAudioFormat", {
157
146
  enumerable: true,
158
- get: function () { return chunkXPY45Y75_js.mimeToAudioFormat; }
147
+ get: function () { return chunkVVHFMAE7_js.mimeToAudioFormat; }
159
148
  });
160
149
  Object.defineProperty(exports, "pickDefaultSttModel", {
161
150
  enumerable: true,
162
- get: function () { return chunkXPY45Y75_js.pickDefaultSttModel; }
151
+ get: function () { return chunkVVHFMAE7_js.pickDefaultSttModel; }
163
152
  });
164
153
  Object.defineProperty(exports, "pickDefaultVisionModel", {
165
154
  enumerable: true,
166
- get: function () { return chunkXPY45Y75_js.pickDefaultVisionModel; }
155
+ get: function () { return chunkVVHFMAE7_js.pickDefaultVisionModel; }
167
156
  });
168
157
  Object.defineProperty(exports, "registerAiTask", {
169
158
  enumerable: true,
170
- get: function () { return chunkXPY45Y75_js.registerAiTask; }
159
+ get: function () { return chunkVVHFMAE7_js.registerAiTask; }
171
160
  });
172
161
  Object.defineProperty(exports, "registerCoreAiTasks", {
173
162
  enumerable: true,
174
- get: function () { return chunkXPY45Y75_js.registerCoreAiTasks; }
163
+ get: function () { return chunkVVHFMAE7_js.registerCoreAiTasks; }
175
164
  });
176
165
  Object.defineProperty(exports, "requestJson", {
177
166
  enumerable: true,
178
- get: function () { return chunkXPY45Y75_js.requestJson; }
167
+ get: function () { return chunkVVHFMAE7_js.requestJson; }
179
168
  });
180
169
  Object.defineProperty(exports, "requireAiConnectionConfig", {
181
170
  enumerable: true,
182
- get: function () { return chunkXPY45Y75_js.requireAiConnectionConfig; }
171
+ get: function () { return chunkVVHFMAE7_js.requireAiConnectionConfig; }
183
172
  });
184
173
  Object.defineProperty(exports, "resetCoreAiTasksForTest", {
185
174
  enumerable: true,
186
- get: function () { return chunkXPY45Y75_js.resetCoreAiTasksForTest; }
175
+ get: function () { return chunkVVHFMAE7_js.resetCoreAiTasksForTest; }
187
176
  });
188
177
  Object.defineProperty(exports, "resolveAiConnectionConfig", {
189
178
  enumerable: true,
190
- get: function () { return chunkXPY45Y75_js.resolveAiConnectionConfig; }
179
+ get: function () { return chunkVVHFMAE7_js.resolveAiConnectionConfig; }
191
180
  });
192
181
  Object.defineProperty(exports, "resolveAudioHandling", {
193
182
  enumerable: true,
194
- get: function () { return chunkXPY45Y75_js.resolveAudioHandling; }
183
+ get: function () { return chunkVVHFMAE7_js.resolveAudioHandling; }
195
184
  });
196
185
  Object.defineProperty(exports, "runAiTask", {
197
186
  enumerable: true,
198
- get: function () { return chunkXPY45Y75_js.runAiTask; }
187
+ get: function () { return chunkVVHFMAE7_js.runAiTask; }
199
188
  });
200
189
  Object.defineProperty(exports, "splitMediaByKind", {
201
190
  enumerable: true,
202
- get: function () { return chunkXPY45Y75_js.splitMediaByKind; }
191
+ get: function () { return chunkVVHFMAE7_js.splitMediaByKind; }
203
192
  });
204
193
  Object.defineProperty(exports, "toVisionApiErrorMessage", {
205
194
  enumerable: true,
206
- get: function () { return chunkXPY45Y75_js.toVisionApiErrorMessage; }
195
+ get: function () { return chunkVVHFMAE7_js.toVisionApiErrorMessage; }
207
196
  });
208
197
  Object.defineProperty(exports, "transcribeAudio", {
209
198
  enumerable: true,
210
- get: function () { return chunkXPY45Y75_js.transcribeAudio; }
199
+ get: function () { return chunkVVHFMAE7_js.transcribeAudio; }
211
200
  });
212
201
  Object.defineProperty(exports, "transcribeAudios", {
213
202
  enumerable: true,
214
- get: function () { return chunkXPY45Y75_js.transcribeAudios; }
203
+ get: function () { return chunkVVHFMAE7_js.transcribeAudios; }
204
+ });
205
+ Object.defineProperty(exports, "CORE_CONNECTIVITY_TEST_TASK_ID", {
206
+ enumerable: true,
207
+ get: function () { return chunkGJVEYCS4_js.CORE_CONNECTIVITY_TEST_TASK_ID; }
208
+ });
209
+ Object.defineProperty(exports, "CORE_LLM_COMPLETION_TASK_ID", {
210
+ enumerable: true,
211
+ get: function () { return chunkGJVEYCS4_js.CORE_LLM_COMPLETION_TASK_ID; }
212
+ });
213
+ Object.defineProperty(exports, "CORE_STRUCTURED_MULTIMODAL_TASK_ID", {
214
+ enumerable: true,
215
+ get: function () { return chunkGJVEYCS4_js.CORE_STRUCTURED_MULTIMODAL_TASK_ID; }
215
216
  });
216
217
  //# sourceMappingURL=index.js.map
217
218
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,5 @@
1
- export { CORE_CONNECTIVITY_TEST_TASK_ID, CORE_LLM_COMPLETION_TASK_ID, CORE_STRUCTURED_MULTIMODAL_TASK_ID, DEFAULT_OPENAI_BASE_URL, DEFAULT_TEXT_MODEL, appendTranscriptionsToPrompt, assertMultimodalCapableModel, assertValidAudioInput, assertValidImageInput, assertValidMultimodalMedia, assertVisionCapableModel, base64ToBlob, buildMultimodalMessages, callChat, callCompletion, callMultimodalChat, clearAiTasksForTest, coreConnectivityTestTask, coreLlmCompletionTask, coreStructuredMultimodalTask, detectVisionMessageFormat, ensureCoreAiTasksRegistered, extractJsonObject, fileToAiAudioInput, fileToAiImageInput, filterChatModels, filterSttModels, filterVisionModels, getAiTask, isAudioInputError, isImageUrlVariantError, isKnownTextOnlyModel, isLikelyNativeAudioChatModel, isLikelySttModel, isLikelyVisionModel, listAiTasks, listOpenAiCompatibleModels, mimeToAudioFormat, pickDefaultSttModel, pickDefaultVisionModel, registerAiTask, registerCoreAiTasks, requestJson, requireAiConnectionConfig, resetCoreAiTasksForTest, resolveAiConnectionConfig, resolveAudioHandling, runAiTask, splitMediaByKind, toVisionApiErrorMessage, transcribeAudio, transcribeAudios } from '../../chunk-ZJLS5JU5.mjs';
1
+ export { DEFAULT_OPENAI_BASE_URL, DEFAULT_TEXT_MODEL, appendTranscriptionsToPrompt, assertMultimodalCapableModel, assertValidAudioInput, assertValidImageInput, assertValidMultimodalMedia, assertVisionCapableModel, base64ToBlob, buildMultimodalMessages, callChat, callCompletion, callMultimodalChat, clearAiTasksForTest, coreConnectivityTestTask, coreLlmCompletionTask, coreStructuredMultimodalTask, detectVisionMessageFormat, ensureCoreAiTasksRegistered, extractJsonObject, fileToAiAudioInput, fileToAiImageInput, filterChatModels, filterSttModels, filterVisionModels, getAiTask, isAudioInputError, isImageUrlVariantError, isKnownTextOnlyModel, isLikelyNativeAudioChatModel, isLikelySttModel, isLikelyVisionModel, listAiTasks, listOpenAiCompatibleModels, mimeToAudioFormat, pickDefaultSttModel, pickDefaultVisionModel, registerAiTask, registerCoreAiTasks, requestJson, requireAiConnectionConfig, resetCoreAiTasksForTest, resolveAiConnectionConfig, resolveAudioHandling, runAiTask, splitMediaByKind, toVisionApiErrorMessage, transcribeAudio, transcribeAudios } from '../../chunk-6KD4CD7O.mjs';
2
+ export { CORE_CONNECTIVITY_TEST_TASK_ID, CORE_LLM_COMPLETION_TASK_ID, CORE_STRUCTURED_MULTIMODAL_TASK_ID } from '../../chunk-PPV4IEWR.mjs';
2
3
  import '../../chunk-MAI35PU6.mjs';
3
4
  //# sourceMappingURL=index.mjs.map
4
5
  //# sourceMappingURL=index.mjs.map
@@ -1,3 +1,3 @@
1
- export { p as AiApiErrorBody, q as AiApiErrorCode, a as AiApiResponse, r as AiApiResponseMeta, n as AiApiRunRequest, g as AiAudioInput, u as AiAudioMediaInput, A as AiClientSettings, d as AiConnectionConfig, m as AiConnectionSettings, f as AiImageInput, t as AiImageMediaInput, h as AiMediaInput, s as AiMediaKind, y as AiModelsListRequest, b as AiModelsListResponse, j as AiTaskContext, i as AiTaskDefinition, o as AiTaskRunOptions, c as AudioStrategy, x as CORE_CONNECTIVITY_TEST_TASK_ID, v as CORE_LLM_COMPLETION_TASK_ID, w as CORE_STRUCTURED_MULTIMODAL_TASK_ID, C as ConnectivityTestOutput, M as MultimodalChatParams, e as MultimodalChatResult, S as StructuredMultimodalInput, l as StructuredMultimodalOutput, T as TextCompletionInput, k as TextCompletionOutput } from '../../../types-CiqMQ-uu.mjs';
1
+ export { q as AiApiErrorBody, r as AiApiErrorCode, a as AiApiResponse, s as AiApiResponseMeta, o as AiApiRunRequest, h as AiAudioInput, v as AiAudioMediaInput, A as AiClientSettings, e as AiConnectionConfig, n as AiConnectionSettings, g as AiImageInput, u as AiImageMediaInput, i as AiMediaInput, t as AiMediaKind, z as AiModelsListRequest, b as AiModelsListResponse, d as AiServerConfigStatus, k as AiTaskContext, j as AiTaskDefinition, p as AiTaskRunOptions, c as AudioStrategy, y as CORE_CONNECTIVITY_TEST_TASK_ID, w as CORE_LLM_COMPLETION_TASK_ID, x as CORE_STRUCTURED_MULTIMODAL_TASK_ID, C as ConnectivityTestOutput, M as MultimodalChatParams, f as MultimodalChatResult, S as StructuredMultimodalInput, m as StructuredMultimodalOutput, T as TextCompletionInput, l as TextCompletionOutput } from '../../../types-DgbG0Of-.mjs';
2
2
  export { CallChatOptions, CallChatResult, CallCompletionParams, CallCompletionResult, ChatMessage, ChatRole, ChatUsage, DEFAULT_OPENAI_BASE_URL, DEFAULT_TEXT_MODEL, JsonRequestOptions, ListModelsResult, ResolvedAudioHandling, TranscribeAudioOptions, VisionMessageFormat, appendTranscriptionsToPrompt, assertMultimodalCapableModel, assertValidAudioInput, assertValidImageInput, assertValidMultimodalMedia, assertVisionCapableModel, base64ToBlob, buildMultimodalMessages, callChat, callCompletion, callMultimodalChat, clearAiTasksForTest, coreConnectivityTestTask, coreLlmCompletionTask, coreStructuredMultimodalTask, detectVisionMessageFormat, ensureCoreAiTasksRegistered, extractJsonObject, fileToAiAudioInput, fileToAiImageInput, filterChatModels, filterSttModels, filterVisionModels, getAiTask, isAudioInputError, isImageUrlVariantError, isKnownTextOnlyModel, isLikelyNativeAudioChatModel, isLikelySttModel, isLikelyVisionModel, listAiTasks, listOpenAiCompatibleModels, mimeToAudioFormat, pickDefaultSttModel, pickDefaultVisionModel, registerAiTask, registerCoreAiTasks, requestJson, requireAiConnectionConfig, resetCoreAiTasksForTest, resolveAiConnectionConfig, resolveAudioHandling, runAiTask, splitMediaByKind, toVisionApiErrorMessage, transcribeAudio, transcribeAudios } from '../index.mjs';
3
3
  import '../../../types-CbTsi9CZ.mjs';
@@ -1,3 +1,3 @@
1
- export { p as AiApiErrorBody, q as AiApiErrorCode, a as AiApiResponse, r as AiApiResponseMeta, n as AiApiRunRequest, g as AiAudioInput, u as AiAudioMediaInput, A as AiClientSettings, d as AiConnectionConfig, m as AiConnectionSettings, f as AiImageInput, t as AiImageMediaInput, h as AiMediaInput, s as AiMediaKind, y as AiModelsListRequest, b as AiModelsListResponse, j as AiTaskContext, i as AiTaskDefinition, o as AiTaskRunOptions, c as AudioStrategy, x as CORE_CONNECTIVITY_TEST_TASK_ID, v as CORE_LLM_COMPLETION_TASK_ID, w as CORE_STRUCTURED_MULTIMODAL_TASK_ID, C as ConnectivityTestOutput, M as MultimodalChatParams, e as MultimodalChatResult, S as StructuredMultimodalInput, l as StructuredMultimodalOutput, T as TextCompletionInput, k as TextCompletionOutput } from '../../../types-CiqMQ-uu.js';
1
+ export { q as AiApiErrorBody, r as AiApiErrorCode, a as AiApiResponse, s as AiApiResponseMeta, o as AiApiRunRequest, h as AiAudioInput, v as AiAudioMediaInput, A as AiClientSettings, e as AiConnectionConfig, n as AiConnectionSettings, g as AiImageInput, u as AiImageMediaInput, i as AiMediaInput, t as AiMediaKind, z as AiModelsListRequest, b as AiModelsListResponse, d as AiServerConfigStatus, k as AiTaskContext, j as AiTaskDefinition, p as AiTaskRunOptions, c as AudioStrategy, y as CORE_CONNECTIVITY_TEST_TASK_ID, w as CORE_LLM_COMPLETION_TASK_ID, x as CORE_STRUCTURED_MULTIMODAL_TASK_ID, C as ConnectivityTestOutput, M as MultimodalChatParams, f as MultimodalChatResult, S as StructuredMultimodalInput, m as StructuredMultimodalOutput, T as TextCompletionInput, l as TextCompletionOutput } from '../../../types-DgbG0Of-.js';
2
2
  export { CallChatOptions, CallChatResult, CallCompletionParams, CallCompletionResult, ChatMessage, ChatRole, ChatUsage, DEFAULT_OPENAI_BASE_URL, DEFAULT_TEXT_MODEL, JsonRequestOptions, ListModelsResult, ResolvedAudioHandling, TranscribeAudioOptions, VisionMessageFormat, appendTranscriptionsToPrompt, assertMultimodalCapableModel, assertValidAudioInput, assertValidImageInput, assertValidMultimodalMedia, assertVisionCapableModel, base64ToBlob, buildMultimodalMessages, callChat, callCompletion, callMultimodalChat, clearAiTasksForTest, coreConnectivityTestTask, coreLlmCompletionTask, coreStructuredMultimodalTask, detectVisionMessageFormat, ensureCoreAiTasksRegistered, extractJsonObject, fileToAiAudioInput, fileToAiImageInput, filterChatModels, filterSttModels, filterVisionModels, getAiTask, isAudioInputError, isImageUrlVariantError, isKnownTextOnlyModel, isLikelyNativeAudioChatModel, isLikelySttModel, isLikelyVisionModel, listAiTasks, listOpenAiCompatibleModels, mimeToAudioFormat, pickDefaultSttModel, pickDefaultVisionModel, registerAiTask, registerCoreAiTasks, requestJson, requireAiConnectionConfig, resetCoreAiTasksForTest, resolveAiConnectionConfig, resolveAudioHandling, runAiTask, splitMediaByKind, toVisionApiErrorMessage, transcribeAudio, transcribeAudios } from '../index.js';
3
3
  import '../../../types-CbTsi9CZ.js';