@ai-wendao/ant 0.4.11 → 0.4.13

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.
package/client.js CHANGED
@@ -5,7 +5,14 @@ window.__ModuleLoader__.load({
5
5
  var exports = module.exports
6
6
  const { createElement, useEffect, useRef, useState } = require('react')
7
7
  const h = createElement
8
+ const compactOpenaiProviderName = (name) => {
9
+ const value = typeof name === 'string' ? name.trim() : ''
10
+ if (!value) return value
11
+ const suffix = /\s*(?:[·•::|—–-]\s*)?(?:Responses|Chat Completions)$/iu
12
+ return value.replace(suffix, '').trim() || 'OpenAI'
13
+ }
8
14
  const SERVICE_URL_STORAGE_KEY = 'ant-team-service-url'
15
+ const PROVIDER_ROUTES_STORAGE_KEY = 'ant-team-provider-routes'
9
16
  const DEVICE_ID_STORAGE_KEY = 'ant-team-device-id'
10
17
  const DEFAULT_MODEL_INITIALIZED_KEY = 'ant-team-default-model-initialized'
11
18
  const ANT_BUNDLE_PACKAGE_NAME = '@ai-wendao/ant'
@@ -1989,9 +1996,12 @@ window.__ModuleLoader__.load({
1989
1996
  return status
1990
1997
  }
1991
1998
 
1992
- const modelProvider = (model) => model.protocol === 'anthropic' ? 'ant-team-anthropic'
1993
- : model.openai_api_mode === 'responses' ? 'ant-team-openai-responses' : 'ant-team-openai-chat-completions'
1994
- const modelSelectionKey = (model) => JSON.stringify({ protocol: model.protocol, model_id: model.model_id })
1999
+ const modelProvider = (model) => model.protocol === 'anthropic'
2000
+ ? model.provider_id === 'anthropic-default' || !model.provider_id ? 'ant-team-anthropic' : `ant-team-anthropic-${model.provider_id}`
2001
+ : model.provider_id === 'openai-default' || !model.provider_id
2002
+ ? model.openai_api_mode === 'responses' ? 'ant-team-openai-responses' : 'ant-team-openai-chat-completions'
2003
+ : `ant-team-openai-${model.provider_id}`
2004
+ const modelSelectionKey = (model) => JSON.stringify({ provider_id: model.provider_id || '', protocol: model.protocol, model_id: model.model_id })
1995
2005
  const defaultPreferenceKey = (rawServiceUrl) => `${DEFAULT_MODEL_INITIALIZED_KEY}:${normalizeServiceUrl(rawServiceUrl)}:${savedDeviceId() || ''}`
1996
2006
  const readDefaultPreference = (rawServiceUrl) => {
1997
2007
  try { return JSON.parse(localStorage.getItem(defaultPreferenceKey(rawServiceUrl)) || 'null') } catch { return null }
@@ -2003,9 +2013,9 @@ window.__ModuleLoader__.load({
2003
2013
  if (!selection) return null
2004
2014
  const exact = models.find((model) => model.model_id === selection.model && modelProvider(model) === selection.provider)
2005
2015
  if (exact) return exact
2006
- const legacyProtocol = selection.provider === 'ant-team-openai' || selection.provider?.startsWith('ant-team-openai-')
2007
- ? 'openai' : selection.provider === 'ant-team-anthropic' ? 'anthropic' : null
2008
- return legacyProtocol ? models.find((model) => model.protocol === legacyProtocol && model.model_id === selection.model) : null
2016
+ const legacyProvider = ['ant-team-openai', 'ant-team-openai-chat-completions', 'ant-team-openai-responses'].includes(selection.provider)
2017
+ ? 'openai-default' : selection.provider === 'ant-team-anthropic' ? 'anthropic-default' : null
2018
+ return legacyProvider ? models.find((model) => model.provider_id === legacyProvider && model.model_id === selection.model) : null
2009
2019
  }
2010
2020
  const readDshDefaultSelection = async () => {
2011
2021
  if (typeof remote?.settings?.describe !== 'function') throw new Error('当前 DSH 未提供全局默认模型读取接口。')
@@ -2051,34 +2061,71 @@ window.__ModuleLoader__.load({
2051
2061
  const normalized = normalizeServiceUrl(rawServiceUrl)
2052
2062
  if (!normalized || !Array.isArray(models)) throw new Error('ANT 返回的团队模型目录格式无效。')
2053
2063
  if (typeof remote?.settings?.mutate !== 'function') throw new Error('当前 DSH 版本未提供模型设置接口。')
2054
- const groups = [
2055
- { route: 'ant-team-openai-chat-completions', protocol: 'openai', mode: 'chat_completions', api: 'openai-completions' },
2056
- { route: 'ant-team-openai-responses', protocol: 'openai', mode: 'responses', api: 'openai-responses' },
2057
- { route: 'ant-team-anthropic', protocol: 'anthropic', api: 'anthropic-messages' },
2058
- ]
2059
- const ops = [{ op: 'unset', path: ['providers', 'ant-team-openai'] }]
2060
- for (const group of groups) {
2061
- const protocolModels = models.filter((model) => model.protocol === group.protocol
2062
- && (group.protocol !== 'openai' || (model.openai_api_mode || 'chat_completions') === group.mode))
2063
- const route = group.route
2064
- if (protocolModels.length === 0) {
2065
- ops.push({ op: 'unset', path: ['providers', route] })
2066
- continue
2064
+ const grouped = new Map()
2065
+ for (const model of models) {
2066
+ const protocol = model.protocol
2067
+ if (!['openai', 'anthropic'].includes(protocol)) continue
2068
+ const providerId = model.provider_id || (protocol === 'openai' ? 'openai-default' : 'anthropic-default')
2069
+ const key = `${providerId}\u0000${protocol}`
2070
+ let provider = grouped.get(key)
2071
+ if (!provider) {
2072
+ const providerName = model.provider_name || (protocol === 'openai'
2073
+ ? 'ANT 团队 · OpenAI' : 'ANT 团队 · Anthropic')
2074
+ provider = {
2075
+ providerId,
2076
+ providerName: protocol === 'openai'
2077
+ ? compactOpenaiProviderName(providerName)
2078
+ : providerName,
2079
+ protocol,
2080
+ apiMode: model.openai_api_mode === 'responses' ? 'responses' : 'chat_completions',
2081
+ legacyEndpoint: typeof model.provider_id !== 'string' || !model.provider_id,
2082
+ models: [],
2083
+ }
2084
+ grouped.set(key, provider)
2067
2085
  }
2086
+ provider.models.push(model)
2087
+ }
2088
+ const providers = [...grouped.values()]
2089
+ const routeForProvider = (provider) => provider.providerId === 'openai-default'
2090
+ ? provider.apiMode === 'responses' ? 'ant-team-openai-responses' : 'ant-team-openai-chat-completions'
2091
+ : provider.providerId === 'anthropic-default'
2092
+ ? 'ant-team-anthropic' : `ant-team-${provider.protocol}-${provider.providerId}`
2093
+ const routes = providers.map(routeForProvider)
2094
+ const ops = []
2095
+ let previousRoutes = []
2096
+ try {
2097
+ const parsed = JSON.parse(localStorage.getItem(PROVIDER_ROUTES_STORAGE_KEY) || '[]')
2098
+ if (Array.isArray(parsed)) previousRoutes = parsed.filter((route) => typeof route === 'string')
2099
+ } catch {}
2100
+ const knownRoutes = new Set([...previousRoutes, 'ant-team-openai', 'ant-team-openai-chat-completions',
2101
+ 'ant-team-openai-responses', 'ant-team-anthropic'])
2102
+ for (const route of knownRoutes) {
2103
+ if (!routes.includes(route)) ops.push({ op: 'unset', path: ['providers', route] })
2104
+ }
2105
+ for (const provider of providers) {
2106
+ const route = routeForProvider(provider)
2107
+ const api = provider.protocol === 'openai'
2108
+ ? provider.apiMode === 'responses' ? 'openai-responses' : 'openai-completions'
2109
+ : 'anthropic-messages'
2110
+ const baseURL = provider.legacyEndpoint
2111
+ ? new URL(provider.protocol === 'openai' ? '/model-gateway/openai/v1' : '/model-gateway/anthropic', normalized).toString()
2112
+ : provider.protocol === 'openai'
2113
+ ? new URL(`/model-gateway/openai/providers/${encodeURIComponent(provider.providerId)}/v1`, normalized).toString()
2114
+ : new URL(`/model-gateway/anthropic/providers/${encodeURIComponent(provider.providerId)}`, normalized).toString()
2068
2115
  ops.push({ op: 'set', path: ['providers', route], value: {
2069
- displayName: group.protocol === 'anthropic' ? 'ANT 团队 · Anthropic' : `ANT 团队 · OpenAI · ${group.mode === 'responses' ? 'Responses' : 'Chat Completions'}`,
2116
+ displayName: provider.providerName,
2070
2117
  apiKeyEnv: 'ANT_MODEL_API_KEY',
2071
- api: group.api,
2072
- baseURL: group.protocol === 'openai'
2073
- ? new URL('/model-gateway/openai/v1', normalized).toString()
2074
- : new URL('/model-gateway/anthropic', normalized).toString(),
2075
- models: protocolModels.map((model) => ({ id: model.model_id, name: model.display_name })),
2118
+ api,
2119
+ baseURL,
2120
+ models: provider.models.map((model) => ({ id: model.model_id, name: model.display_name })),
2076
2121
  } })
2077
2122
  }
2078
2123
  const settingsWrite = await remote.settings.mutate('llm-pi-ai', ops, undefined)
2079
2124
  if (!settingsWrite.ok) throw new Error(settingsWrite.error?.message || 'DSH 无法更新团队模型设置。')
2080
- const defaultMatch = rawDefaultModel && models.find((model) => model.protocol === rawDefaultModel.protocol
2081
- && model.model_id === rawDefaultModel.model_id)
2125
+ try { localStorage.setItem(PROVIDER_ROUTES_STORAGE_KEY, JSON.stringify(routes)) } catch {}
2126
+ const defaultMatch = rawDefaultModel && models.find((model) =>
2127
+ (rawDefaultModel.provider_id ? model.provider_id === rawDefaultModel.provider_id : model.protocol === rawDefaultModel.protocol)
2128
+ && model.protocol === rawDefaultModel.protocol && model.model_id === rawDefaultModel.model_id)
2082
2129
  const serverDefault = defaultMatch || null
2083
2130
  const initialDefault = defaultMatch || (rawDefaultModel == null ? models[0] : null)
2084
2131
  setServerDefaultModel(serverDefault)
@@ -2138,7 +2185,9 @@ window.__ModuleLoader__.load({
2138
2185
  setModelMessage('正在从 ANT 刷新获准模型…')
2139
2186
  try {
2140
2187
  await requireCompatibleService(serviceUrl, true)
2141
- const response = await fetch('/api/ant-teams/models', { method: 'POST' })
2188
+ const response = await fetch('/api/ant-teams/models', {
2189
+ method: 'POST', headers: { 'x-ant-model-provider-config': '1' },
2190
+ })
2142
2191
  const result = await readLocalJsonResponse(response)
2143
2192
  if (!response.ok) {
2144
2193
  if (response.status === 401) setNeedsReconnect(true)
@@ -2327,13 +2376,26 @@ window.__ModuleLoader__.load({
2327
2376
  ], undefined)
2328
2377
  if (!reset.ok) throw new Error(reset.error?.message || 'DSH 全局默认模型未能恢复。')
2329
2378
  }
2330
- const settingsResult = await remote.settings.mutate('llm-pi-ai', [
2331
- { op: 'unset', path: ['providers', 'ant-team-openai-chat-completions'] },
2332
- { op: 'unset', path: ['providers', 'ant-team-openai-responses'] },
2333
- { op: 'unset', path: ['providers', 'ant-team-openai'] },
2334
- { op: 'unset', path: ['providers', 'ant-team-anthropic'] },
2335
- ], undefined)
2379
+ let managedRoutes = []
2380
+ try {
2381
+ const parsed = JSON.parse(localStorage.getItem(PROVIDER_ROUTES_STORAGE_KEY) || '[]')
2382
+ if (Array.isArray(parsed)) managedRoutes = parsed.filter((route) => typeof route === 'string')
2383
+ } catch {}
2384
+ if (typeof remote?.settings?.describe === 'function') {
2385
+ const described = await remote.settings.describe()
2386
+ if (!described?.ok) throw new Error(described?.error?.message || '无法读取 DSH 中的 ANT 提供方列表。')
2387
+ const providers = described.value?.namespaces?.find((item) => item.ns === 'llm-pi-ai')?.value?.providers
2388
+ for (const [route, provider] of Object.entries(providers || {})) {
2389
+ if (route.startsWith('ant-team-') && provider?.apiKeyEnv === 'ANT_MODEL_API_KEY') managedRoutes.push(route)
2390
+ }
2391
+ }
2392
+ const routes = new Set([...managedRoutes, 'ant-team-openai-chat-completions', 'ant-team-openai-responses',
2393
+ 'ant-team-openai', 'ant-team-anthropic'])
2394
+ const settingsResult = await remote.settings.mutate('llm-pi-ai', [...routes].map((route) => ({
2395
+ op: 'unset', path: ['providers', route],
2396
+ })), undefined)
2336
2397
  if (!settingsResult.ok) throw new Error(settingsResult.error?.message || 'ANT 模型设置未能清除。')
2398
+ try { localStorage.removeItem(PROVIDER_ROUTES_STORAGE_KEY) } catch {}
2337
2399
  if (typeof remote?.credentials?.unset !== 'function') throw new Error('DSH 未提供凭证删除接口。')
2338
2400
  const credentialResult = await remote.credentials.unset('ANT_MODEL_API_KEY')
2339
2401
  if (!credentialResult.ok) throw new Error(credentialResult.error?.message || 'ANT 成员凭证未能清除。')
@@ -2500,7 +2562,7 @@ window.__ModuleLoader__.load({
2500
2562
  localStorage.setItem(SERVICE_URL_STORAGE_KEY, normalized)
2501
2563
  const response = await fetch('/api/ant-teams/connect', {
2502
2564
  method: 'POST',
2503
- headers: { 'Content-Type': 'application/json' },
2565
+ headers: { 'Content-Type': 'application/json', 'x-ant-model-provider-config': '1' },
2504
2566
  body: JSON.stringify({
2505
2567
  service_url: normalized,
2506
2568
  email: normalizedEmail,
@@ -2551,14 +2613,19 @@ window.__ModuleLoader__.load({
2551
2613
  const updateGuideUrl = pinnedServiceUrl
2552
2614
  ? new URL('/ant-update', pinnedServiceUrl).href : null
2553
2615
  const currentDshDefaultModel = modelForProviderSelection(dshDefaultSelection, authorizedModels)
2554
- const modelRows = authorizedModels.map((model) => h('div', { key: `${model.protocol}:${model.model_id}`, role: 'listitem',
2555
- style: { display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(120px, auto) minmax(130px, auto)',
2556
- gap: 12, alignItems: 'center', padding: '10px 2px', borderBottom: '1px solid var(--dsw-alias-border-l2)' } },
2557
- h('strong', { style: { minWidth: 0, overflowWrap: 'anywhere' } }, model.display_name || model.model_id),
2558
- h('span', { style: { display: 'inline-flex', justifySelf: 'start', padding: '3px 8px', borderRadius: 999,
2559
- backgroundColor: 'var(--dsw-alias-bg-layer-2)', color: 'var(--dsw-alias-label-secondary)', fontSize: 12 } },
2560
- model.protocol === 'anthropic' ? 'Anthropic Messages' : `OpenAI · ${(model.openai_api_mode || 'chat_completions') === 'responses' ? 'Responses' : 'Chat Completions'}`),
2561
- h('span', { style: { ...mutedTextStyle, textAlign: 'right' } }, '已同步到 DSH')))
2616
+ const modelRows = authorizedModels.map((model) => {
2617
+ const providerName = model.protocol === 'openai'
2618
+ ? compactOpenaiProviderName(model.provider_name)
2619
+ : model.provider_name
2620
+ return h('div', { key: `${model.provider_id || ''}:${model.protocol}:${model.model_id}`, role: 'listitem',
2621
+ style: { display: 'grid', gridTemplateColumns: 'minmax(0, 1fr) minmax(120px, auto) minmax(130px, auto)',
2622
+ gap: 12, alignItems: 'center', padding: '10px 2px', borderBottom: '1px solid var(--dsw-alias-border-l2)' } },
2623
+ h('strong', { style: { minWidth: 0, overflowWrap: 'anywhere' } }, `${providerName ? `${providerName} · ` : ''}${model.display_name || model.model_id}`),
2624
+ h('span', { style: { display: 'inline-flex', justifySelf: 'start', padding: '3px 8px', borderRadius: 999,
2625
+ backgroundColor: 'var(--dsw-alias-bg-layer-2)', color: 'var(--dsw-alias-label-secondary)', fontSize: 12 } },
2626
+ model.protocol === 'anthropic' ? 'Anthropic Messages' : `OpenAI · ${model.openai_api_mode === 'responses' ? 'Responses' : 'Chat Completions'}`),
2627
+ h('span', { style: { ...mutedTextStyle, textAlign: 'right' } }, '已同步到 DSH'))
2628
+ })
2562
2629
  const connectionPanel = h('section', { style: { ...settingsPanelStyle, display: activeTab === 'connection' ? 'grid' : 'none' } },
2563
2630
  h('div', null,
2564
2631
  h('h3', { style: sectionTitleStyle }, 'ANT 团队账号'),
@@ -2615,7 +2682,8 @@ window.__ModuleLoader__.load({
2615
2682
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 } },
2616
2683
  h('div', null,
2617
2684
  h('h3', { style: sectionTitleStyle }, '团队模型'),
2618
- h('p', { style: { ...mutedTextStyle, marginTop: 4 } }, '每个获准模型单独列出;刷新后同步到 DSH 模型选择器。')),
2685
+ h('p', { style: { ...mutedTextStyle, marginTop: 4 } }, '每个获准模型单独列出;刷新后同步到 DSH 模型选择器。'),
2686
+ h('p', { style: { ...mutedTextStyle, marginTop: 4 } }, 'API 模式由 ANT 团队提供方设置统一控制,作用于该提供方下的所有模型。DSH 设置中的模式只影响当前 Profile,不会修改服务器;模式不匹配会导致请求失败,刷新团队模型会重新应用团队设置。')),
2619
2687
  h('span', { style: { flexShrink: 0, padding: '4px 9px', borderRadius: 999,
2620
2688
  color: credentialConfigured === true && bindingReady ? 'var(--dsw-alias-state-success-primary)' : 'var(--dsw-alias-label-secondary)',
2621
2689
  backgroundColor: credentialConfigured === true && bindingReady ? 'var(--dsw-alias-state-success-tertiary)' : 'var(--dsw-alias-bg-layer-2)',
@@ -2633,8 +2701,14 @@ window.__ModuleLoader__.load({
2633
2701
  disabled: credentialConfigured !== true || !authorizedModels.length || defaultModelBusy || busy,
2634
2702
  onChange: (event) => setDefaultModelDraft(event.target.value), style: inputStyle },
2635
2703
  h('option', { value: '' }, '选择获准模型'),
2636
- ...authorizedModels.map((model) => h('option', { key: modelSelectionKey(model), value: modelSelectionKey(model) },
2637
- `${model.display_name || model.model_id} · ${model.protocol === 'anthropic' ? 'Anthropic' : (model.openai_api_mode || 'chat_completions') === 'responses' ? 'OpenAI Responses' : 'OpenAI Chat Completions'}`)))),
2704
+ ...authorizedModels.map((model) => {
2705
+ const providerName = model.protocol === 'openai'
2706
+ ? compactOpenaiProviderName(model.provider_name)
2707
+ : model.provider_name
2708
+ const protocolName = model.protocol === 'anthropic' ? 'Anthropic' : `OpenAI ${model.openai_api_mode === 'responses' ? 'Responses' : 'Chat Completions'}`
2709
+ return h('option', { key: modelSelectionKey(model), value: modelSelectionKey(model) },
2710
+ `${providerName ? `${providerName} · ` : ''}${model.display_name || model.model_id} · ${protocolName}`)
2711
+ }))),
2638
2712
  h('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' } },
2639
2713
  h('button', { type: 'button', disabled: defaultModelBusy || !defaultModelDraft,
2640
2714
  onClick: () => { const chosen = authorizedModels.find((model) => modelSelectionKey(model) === defaultModelDraft); void applyUserDefaultModel(chosen) },
package/conversation.js CHANGED
@@ -167,8 +167,14 @@ async function prompt(ctx, sessionId, content, signal) {
167
167
  }
168
168
 
169
169
  export function teamModelProvider(model) {
170
- if (model.protocol === 'anthropic') return 'ant-team-anthropic'
171
- return model.openai_api_mode === 'responses' ? 'ant-team-openai-responses' : 'ant-team-openai-chat-completions'
170
+ if (model.protocol === 'anthropic') {
171
+ return !model.provider_id || model.provider_id === 'anthropic-default'
172
+ ? 'ant-team-anthropic' : `ant-team-anthropic-${model.provider_id}`
173
+ }
174
+ if (!model.provider_id || model.provider_id === 'openai-default') {
175
+ return model.openai_api_mode === 'responses' ? 'ant-team-openai-responses' : 'ant-team-openai-chat-completions'
176
+ }
177
+ return `ant-team-openai-${model.provider_id}`
172
178
  }
173
179
 
174
180
  function dshDefaultSelection(ctx) {
@@ -182,8 +188,9 @@ export async function modelFor(ctx, memberJson, connection) {
182
188
  const selection = dshDefaultSelection(ctx)
183
189
  const localDefault = selection && models.find((item) => item.model_id === selection.model
184
190
  && teamModelProvider(item) === selection.provider)
185
- const serverDefault = catalog.default_model && models.find((item) => item.protocol === catalog.default_model.protocol
186
- && item.model_id === catalog.default_model.model_id)
191
+ const serverDefault = catalog.default_model && models.find((item) =>
192
+ (catalog.default_model.provider_id ? item.provider_id === catalog.default_model.provider_id : item.protocol === catalog.default_model.protocol)
193
+ && item.protocol === catalog.default_model.protocol && item.model_id === catalog.default_model.model_id)
187
194
  const model = localDefault || serverDefault || (!Object.hasOwn(catalog, 'default_model') ? models[0] : null)
188
195
  if (!model && models.length) throw new Error('当前没有可用的 ANT 默认模型;请在插件“团队模型”中选择本机默认,或联系管理员检查授权。')
189
196
  if (!model) throw new Error('当前没有可用的团队模型。')
package/index.js CHANGED
@@ -69,8 +69,10 @@ function modelServiceBinding(settings) {
69
69
  let url
70
70
  try { url = new URL(provider.baseURL) } catch { return { configured, serviceUrl: null } }
71
71
  const localHttp = url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname)
72
- if ((url.protocol !== 'https:' && !localHttp) || url.username || url.password || url.search || url.hash
73
- || !['/model-gateway/openai/v1', '/model-gateway/anthropic'].includes(url.pathname)) {
72
+ const knownRoute = ['/model-gateway/openai/v1', '/model-gateway/anthropic'].includes(url.pathname)
73
+ || /^\/model-gateway\/openai\/providers\/[A-Za-z0-9-]{1,64}\/v1$/u.test(url.pathname)
74
+ || /^\/model-gateway\/anthropic\/providers\/[A-Za-z0-9-]{1,64}$/u.test(url.pathname)
75
+ if ((url.protocol !== 'https:' && !localHttp) || url.username || url.password || url.search || url.hash || !knownRoute) {
74
76
  return { configured, serviceUrl: null }
75
77
  }
76
78
  origins.add(url.origin)
@@ -178,7 +180,11 @@ async function fetchMemberModels(request, credentials, settings) {
178
180
  }
179
181
  if (!session.ok) return jsonResponse(502, { message: '无法激活 ANT 模型会话。' })
180
182
  const upstream = await fetch(new URL('/api/me/models', serviceUrl), {
181
- headers: { authorization: `Bearer ${token}`, accept: 'application/json' },
183
+ headers: {
184
+ authorization: `Bearer ${token}`,
185
+ accept: 'application/json',
186
+ ...(request.headers.get('x-ant-model-provider-config') === '1' ? { 'x-ant-model-provider-config': '1' } : {}),
187
+ },
182
188
  redirect: 'manual',
183
189
  signal: AbortSignal.timeout(10_000),
184
190
  })
@@ -865,6 +871,8 @@ async function fetchAuthRequest(request, endpoint, credentials, settings) {
865
871
  accept: 'application/json',
866
872
  'content-type': 'application/json',
867
873
  origin: serviceUrl,
874
+ ...(endpoint === 'dsh-connect' && request.headers.get('x-ant-model-provider-config') === '1'
875
+ ? { 'x-ant-model-provider-config': '1' } : {}),
868
876
  },
869
877
  body: JSON.stringify(payload),
870
878
  redirect: 'manual',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-wendao/ant",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "description": "ANT (AI-native Teams) connects a DeepSeek Harness Desktop profile to team identity and approved models.",
5
5
  "type": "module",
6
6
  "scripts": {